5

我有一个带有表的sqlite DB samplesurveytype并且status所有3个表的主键ID都设置为表“操作”的外键。请参见下图中的scema

在此处输入图像描述

我的operation桌子有因此值

在此处输入图像描述

并采样为

在此处输入图像描述

和状态

在此处输入图像描述

调查类型为

在此处输入图像描述

必需的

我需要实现的是

在此处输入图像描述

从操作表中获取状态 id的信息,并针对所有调查类型的特定建筑物显示它。

试过了

我找到了一种通过程序循环获取所有样本ID和所有调查类型ID并获取单个状态ID的方法

for all sampleid in sample table
{
   for all statustypeid in statustype table
   {  
      select statusid from operation where sampleid = 2 and surveytypeid=1
    }
}

sql单一查询是否有更好的选择来生成包含所有值的表

注意:使用 sqlite,适用于 ios 应用程序

4

5 回答 5

1

首先:为什么 Operation.StatusID 是 Text 类型的,当它填充来自整数字段的值时?关于 RegionID 的问题也可能相同,但由于此处未列出 Region 表,我无法确定,在这种特殊情况下,您可能需要 Text。但是将 Operation.StatusID 作为 Text 是完全不合理的,并且会给您带来性能损失。

尽管如此,有一个古老的技巧,称为旋转,但它只适用于固定数量的列,在你的情况下 - 调查:

SELECT
  Sample.BuildingID,
  MAX(Sample.BuildingName_EN) BuildingID,
  MAX(CASE WHEN Operation.SurveyTypeID=1 THEN Operation.StatusID ELSE " " END) AS Survey1,
  MAX(CASE WHEN Operation.SurveyTypeID=2 THEN Operation.StatusID ELSE " " END) AS Survey2,
  MAX(CASE WHEN Operation.SurveyTypeID=3 THEN Operation.StatusID ELSE " " END) AS Survey3
FROM Sample,Operation
WHERE Operation.SampleID=Sample.ID
GROUP BY Sample.BuildingID

更新:为确保此解决方案的可扩展性,您必须在每次使用另一个查询之前生成此查询:

SELECT '  SELECT Sample.BuildingID,MAX(Sample.BuildingName_EN) BuildingID,'
UNION ALL
SELECT concat(' MAX(CASE WHEN Operation.SurveyTypeID=',SurveyType.ID,' THEN Operation.StatusID ELSE " " END) AS "',SurveyType.LongName,'",') from SurveyType
UNION ALL
SELECT '0 as dummy FROM Sample,Operation WHERE Operation.SampleID=Sample.ID GROUP BY Sample.BuildingID'

或者,对于 Oracle 和 SQLite:

SELECT '  SELECT Sample.BuildingID,MAX(Sample.BuildingName_EN) BuildingID,'
UNION ALL
SELECT ' MAX(CASE WHEN Operation.SurveyTypeID='||SurveyType.I||' THEN Operation.StatusID ELSE " " END) AS "'||SurveyType.LongName||'",' from SurveyType
UNION ALL
SELECT '0 as dummy FROM Sample,Operation WHERE Operation.SampleID=Sample.ID GROUP BY Sample.BuildingID'
于 2013-05-29T08:13:31.773 回答
0

我不会讨论模型本身,但存在一对多Sample[1]-[*]Operation的关系。因此,如果您想在 SQL 行中查询样本的所有操作,您必须编写子选择。这只有在可能的操作数量固定并且我假设它是动态的情况下才能完成。

更常见的方法是使用重复 od 样本条目来 qyery 关系并在代码中处理它

SELECT s.building_name, s.building_id, o.statusID 
from sample s, operation o
where s.id = o.sampleid

另一种方法是在单独的查询中为给定状态选择操作。

SELECT o.statusID 
operation o
where o.sampleid  = 12 
于 2013-05-29T07:47:29.553 回答
0

您需要旋转数据,不幸的是在 mysql 中您无法动态实现这一点。

试试这个:

SELECT
    s.BuildingName_EN as building_name,
    s.ID building_id,
    SUM(CASE WHEN st.LongName = 'Survey1' THEN sa.ID ELSE 0 END) as Survey1,
    SUM(CASE WHEN st.LongName = 'Survey2' THEN sa.ID ELSE 0 END) as Survey2,
    SUM(CASE WHEN st.LongName = 'New Survey 3' THEN sa.ID ELSE 0 END) as 'New Survey 3'
FROM 
    Operation o
LEFT JOIN Sample s
    ON o.SampleID = s.ID 
LEFT JOIN Status sa
    ON o.StatusID = sa.ID 
LEFT JOIN SurveyType st
    ON o.SurveyTypeID = st.ID 
GROUP BY
    s.ID
于 2013-05-29T07:50:56.033 回答
0

您需要为每种调查类型提供一列。这是不可能直接实现的,因为 SQLite 没有数据透视函数。

你需要做两个步骤。首先,获取所有调查类型:

SELECT ID, Longname FROM SurveyType

然后,使用这些值为每个调查类型列构造一个带有一个子查询的查询,如下所示:

SELECT BuildingName_EN AS 'Building Name',
       BuildingID AS 'Building id',
       (SELECT StatusID FROM Operation
        WHERE SampleID = Sample.ID AND SurveyTypeID = 1) AS 'Survey 1',
       (SELECT StatusID FROM Operation
        WHERE SampleID = Sample.ID AND SurveyTypeID = 2) AS 'Survey 2',
       (SELECT StatusID FROM Operation
        WHERE SampleID = Sample.ID AND SurveyTypeID = 3) AS 'New Survey 3'
FROM Sample
于 2013-05-29T07:52:12.807 回答
0
For this first you have to join two tables like : Operation and Sample with SurveyType and then pivot the column 'LongName' of SurveyType. We can achieve it dynamically. 

Here is the query...



Select * FROM 
(Select Sample.BuildingName_EN AS 'Building Name', 
        Sample.BuildingID,
        SurveyType.LongName,
        Operation.StatusID 
from SurveyType
Inner Join Operation ON 
    Operation.SurveyTypeID = SurveyType.ID
Inner Join Sample ON
    Operation.SampleID = Sample.ID
    ) P
PIVOT
(
MAX(StatusID)
FOR LongName
IN ([Survey 1],[Survey 2],[New Survey 3])
) AS pvt
于 2013-05-29T16:35:38.207 回答