我有一个带有表sample
,surveytype
和status
的sqlite数据库。所有3个表的主键id被设置为表'Operation'的外键。请参阅中的scema以下图片
我的operation
表因此具有值
并以
为样本
和状态
和调查类型为
REQUIRED
我需要实现的是
从操作表中获取状态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
答案 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