SQL查询此要求

时间:2013-05-29 07:14:54

标签: mysql ios sql sqlite

我有一个带有表samplesurveytypestatus的sqlite数据库。所有3个表的主键id被设置为表'Operation'的外键。请参阅中的scema以下图片

enter image description here

我的operation表因此具有值

enter image description here

并以

为样本

enter image description here

和状态

enter image description here

和调查类型为

enter image description here

REQUIRED

我需要实现的是

enter image description here

从操作表中获取状态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 single query是否有更好的选项来生成包含所有值的表

注意:使用sqlite,适用于ios app

5 个答案:

答案 0 :(得分: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'

答案 1 :(得分:0)

我不讨论模型本身,但有一对多关系 Sample [1] - [*] Operation 。 因此,如果要在SQL行中查询样本的所有操作,则必须编写子选择。 只有当thre是固定的操作量并且我认为它是动态的时候才能这样做。

更常见的方法是与样本条目的复制进行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 

答案 2 :(得分: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

答案 3 :(得分: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

答案 4 :(得分: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