我有下表(SQL Server)表名是LandParcels
Blockid ParcelNo Stateorprivate
========================
11001901 30 Deemana
11001901 35 Deemana
11001901 41 State
11001901 45 State
11001901 110 Private
11001901 111 Private
11001902 1 Deemana
11001902 11 State
11001902 16 Private
11002001 15 Deemana
11002001 16 State
11003001 20 Private
11002003 2 Deemana
11002003 3 State
11003003 4 Private
Blockid(数字)=用于地籍图号码的前6位数字和用于块号码的最后2位数字
例如:110019是地籍地图no,01是Block No.
我使用了以下查询
select substring(ltrim(str(blockid)),1,6) as blockid,stateorprivate, count(*) as noofLP from LandParcels group by blockid, stateorprivate order by blockid asc
结果是
Blockid Stateorprivate noofLP
========================
110019 Deemana 2
110019 State 2
110019 Private 2
110019 Deemana 1
110019 State 1
110019 Private 1
110020 Deemana 1
110020 State 1
110020 Private 1
110020 Deemana 1
110020 State 1
110020 Private 1
我想获得报告的以下结果
blockid noofBlocks Deemana State Private Amt_of_Deemana_State_Private
110019 2 3 3 3 9
110020 2 2 2 2 6
如何查询。 Pl帮助我。
答案 0 :(得分:2)
我不会检查这是否有效,但你应该看一下使用sum和case。
select
substring(ltrim(str(blockid)),1,6) as blockid,
sum(case stateorprivate when 'Deemana' then 1 else 0 end) as Deemana,
sum(case stateorprivate when 'State' then 1 else 0 end) as State,
sum(case stateorprivate when 'Private' then 1 else 0 end) as Private,
count(*) as Amt_of_Deemana_State_Private
from LandParcels group by blockid
order by blockid asc
答案 1 :(得分:1)
您开始查询:
select substring(ltrim(str(blockid)),1,6) as blockid
会立即给DB带来歧义 - 在查询的其余部分,blockid
代表该名称的原始列,还是代表这个同名的?
不要这样做 - 让数据库引擎过载比现有的处理更加模糊是荒谬的。当 是您的意思时,请使用as myblockid
或此处的任何内容以及myblockid
查询的其余部分。这可能无法解决所有问题,但它会让你的生活,数据库引擎,以及任何试图帮助你的人,更不用说噩梦了。
答案 2 :(得分:1)
你可以这样做:
SELECT
SUBSTRING(LTRIM(STR(Blockid)), 1, 6) AS blockid,
COUNT(DISTINCT SUBSTRING(LTRIM(STR(Blockid)), 7, 2)) AS noofBlocks,
SUM(CASE Stateorprivate WHEN 'Deemana' THEN 1 ELSE 0 END) AS Deemana,
SUM(CASE Stateorprivate WHEN 'State' THEN 1 ELSE 0 END) AS [State],
SUM(CASE Stateorprivate WHEN 'Private' THEN 1 ELSE 0 END) AS [Private],
SUM(CASE Stateorprivate
WHEN 'Deemana' THEN 1
WHEN 'State' THEN 1
WHEN 'Private' THEN 1
ELSE 0
END) AS Amt_of_Deemana_State_Private
FROM LandParcels
GROUP BY SUBSTRING(LTRIM(STR(Blockid)), 1, 6)
但是,如果数据库架构在您的控制之下,则应考虑进行规范化。
答案 3 :(得分:0)
这样的东西?
SELECT substring(ltrim(str(lp.blockid)),1,6) as blockid,
w.noofBlocks
x.Deemana,
y.State,
z.Private,
COUNT(*) AS Amt_of_Deemana_State_Private
FROM LandParcels lp
INNER JOIN (
SELECT substring(ltrim(str(lp.blockid)),1,6) as myblockid, COUNT(*) AS Deemana
FROM LandParcels lp2
WHERE Stateorprivate = 'Deemana'
) x ON (substring(ltrim(str(lp.blockid)),1,6) = x.myblockid)
INNER JOIN (
SELECT substring(ltrim(str(lp.blockid)),1,6) as myblockid, COUNT(*) AS State
FROM LandParcels lp3
WHERE Stateorprivate = 'State'
) y ON (substring(ltrim(str(lp.blockid)),1,6) = y.myblockid)
INNER JOIN (
SELECT substring(ltrim(str(lp.blockid)),1,6) as myblockid, COUNT(*) AS Private
FROM LandParcels lp4
WHERE Stateorprivate = 'Private'
) z ON (substring(ltrim(str(lp.blockid)),1,6) = z.myblockid)
CROSS JOIN (
SELECT COUNT(DISTINCT substring(ltrim(str(lp.blockid)),1,6) as myblockid)
FROM LandParcels lp5
) w
GROUP BY substring(ltrim(str(lp.blockid)),1,6)
答案 4 :(得分:0)
我相信此查询将达到您想要的结果,但NoOfBlocks字段是第一列而不是第二列。我还使用CadastalMapNo作为结果集列名而不是结果集来自Alex Martelli的建议,它增加了歧义,因为已经存在其他名为blockid的东西。我将NoOfBlocks字段作为第一列的原因是因为我认为当使用distinct关键字时,SQLServer要求count函数成为选择列表中的第一个字段。
我实际上没有对此进行过测试,而且性能可能不佳,但我很清楚这是正确的,因为我理解这个问题。
SELECT
COUNT(DISTINCT SUBSTRING(LTRIM(STR(blockid)),7,8)) as NoOfBlocks,
SUBSTRING(LTRIM(STR(blockid)),1,6) as CadastalMapNo,
(CASE WHEN Stateorprivate='Deemana' then 1 else 0 end) as Deemana,
(CASE WHEN Stateorprivate='State' then 1 else 0 end) as State,
(CASE WHEN Stateorprivate='Private' then 1 else 0 end) as Private,
COUNT(*) as Amt_of_Deemana_State_Private
FROM
LandParcels
GROUP BY
CadastalMapNo
ORDER BY
CadastalMapNo