我试图选择记录并使用特定列的值对其进行排序。
将用户分配到特定区域或区域(与districtid和areaid相关联)。 AreaID为5且DistirctID为0的用户可以对他/她区域内跨越多个区域的所有数据进行编辑访问。 AreaID为5且DistirctID为8的用户只能对该区域内的所有数据进行编辑访问。
为了防止用户分页查找数据,我想在桌面上显示他们的数据。不知道如何设置“order by”(由districtid命令,但希望districtid 8在顶部)。有可能吗?
这在ASP.NET(C#)应用程序中使用。
假设我正在尝试为分配给AreaID 5和DistrictID 8的用户显示数据:
select col1, col2, ..., colN from SomeTable order by DistrictID ... (?)
数据库是SQL Server 2016。
更新
这是我试过的:
select distinct ml.MPOOID, ml.MPOOName, ml.AreaID, ml.DistrictID,
zc.AreaName, zc.DistrictName
from MPOO_List ml
left join ZIPCodes zc ON ml.AreaID = zc.AreaID AND ml.DistrictID = zc.DistrictID
where ml.DistrictID=34
union
select distinct ml.MPOOID, ml.MPOOName, ml.AreaID, ml.DistrictID, zc.AreaName, zc.DistrictName
from MPOO_List ml
left join ZIPCodes zc ON ml.AreaID = zc.AreaID AND ml.DistrictID = zc.DistrictID
where ml.DistrictID<>34
如果我遗漏了左连接,它就可以了。
我是否也可以通过MPOOName在每个小组内订购?
更新2
使用AreaID = 5和DistrictID = 34(对于具有分区访问权限的用户),这是有效的。它显示了625条记录中的516条,但是记录按照需要排序:所有区域ID为5且区域ID为34的记录都位于顶部。
为了包含缺失的记录,我尝试在第二个WHERE子句中将“AND”更改为“OR”。这给了我正确的625条记录,但不再符合要求。
如果我向SELECT添加其他列,则会发生同样的事情。即将select更改为SELECT ml.MPOOID,ml.MPOOName,ml.ManagerFirstName,ml.ManagerLastName,ml.Phone,ml.Email,ml.AreaID,ml.DistrictID,ml.StartDate,zc.AreaName,zc.DistrictName。这将返回29,196或35,191条记录,具体取决于我是否在第二个WHERE子句中使用“AND”或“OR”(需要10秒才能执行)
SELECT DISTINCT ml.MPOOID, ml.MPOOName, ml.AreaID, ml.DistrictID
FROM MPOO_List ml
LEFT JOIN ZIPCodes zc ON ml.AreaID = zc.AreaID AND ml.DistrictID = zc.DistrictID
WHERE ml.AreaID = 5 AND ml.DistrictID = 34
UNION
SELECT DISTINCT ml.MPOOID, ml.MPOOName, ml.AreaID, ml.DistrictID
FROM MPOO_List ml
LEFT JOIN ZIPCodes zc ON ml.AreaID <> zc.AreaID AND ml.DistrictID <> zc.DistrictID
where ml.AreaID <> 5 AND ml.DistrictID <> 34
所需的实际选定列:
SELECT ml.MPOOID, ml.MPOOName, ml.FirstName, ml.LastName, ml.Phone, ml.Email, ml.AreaID, ml.DistrictID, ml.StartDate, zc.AreaName, zc.DistrictName
更新3 - 示例数据库表和数据
CREATE TABLE [MPOO_List](
[MPOOID] [int] NOT NULL,
[MPOOName] [varchar](100) NOT NULL,
[FirstName] [varchar](50) NULL,
[LastName] [varchar](50) NULL,
[Phone] [varchar](14) NULL,
[Email] [varchar](100) NULL,
[AreaID] [int] NULL,
[DistrictID] [int] NULL,
[StartDate] [datetime2](0) NULL,
[DefaultMPOO] [bit] NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [MPOO_Zips](
[MPOOID] [int] NOT NULL,
[AreaID] [int] NOT NULL,
[DistrictID] [int] NOT NULL,
[ZipCode] [varchar](5) NOT NULL
) ON [PRIMARY]
GO
insert into MPOO_List values(1000,'PDC','Mary','Jane','(555) 888-7650', 'mary.jane@here.com', 5,23,'2017-03-17 15:49:57',0);
insert into MPOO_List values(1001,'NDC','John','Doe','(555) 888-7621','john.doe@there.com',5,23,'2015-10-01 11:17:08',0);
insert into MPOO_List values(1103,'MPOO 2','Ann','Nonymous','(555) 888-2149','ann.Nonymous@here.com',5,55,'2018-03-23 09:59:06',0);
insert into MPOO_List values(1104,'MPOO 3','Homer','Simpson','(555) 251-0423','homer.simpson@fbi.gov',5,55,'2018-03-23 09:55:50',0);
insert into MPOO_List values(2203,'MPOO 2','Bart','Simpson','(555) 670-6075','bart.simpson@nasa.gov',11,44,'2016-09-20 06:26:43',0);
insert into MPOO_List values(2204,'MPOO 0','Lisa','Simpson','(555) 523-2138','lisa.simpson@mtv.gov',11,44,'2016-09-17 05:45:14',0);
insert into mpoo_zips values (1000,5,23,50265);
insert into mpoo_zips values (1000,5,23,50266);
insert into mpoo_zips values (1000,5,23,50307);
insert into mpoo_zips values (1001,5,23,50533);
insert into mpoo_zips values (1001,5,23,50535);
insert into mpoo_zips values (1001,5,23,50536);
insert into mpoo_zips values (1103,5,55,56341);
insert into mpoo_zips values (1103,5,55,56342);
insert into mpoo_zips values (1103,5,55,56353);
insert into mpoo_zips values (1104,5,55,56450);
insert into mpoo_zips values (1104,5,55,56449);
insert into mpoo_zips values (1104,5,55,56452);
insert into mpoo_zips values (2204,11,4,20006);
insert into mpoo_zips values (2204,11,44,20033);
insert into mpoo_zips values (2204,11,44,20035);
假设我想要AreaID 11的数据,则区域ID 44位于顶部。
答案 0 :(得分:0)
您可以使用UNION连接两个查询,第一个查询与当前区域和区域选择(WHERE AreaID = 5 AND DistrictID = 8
),第二个查询与其相反(WHERE NOT(AreaID = 5 AND DistrictID = 8
)。
SELECT /* some columns */ FROM mytable
WHERE AreaID = 5 AND DistrictID = 8
UNION
SELECT /* the same columns */ FROM mytable
WHERE NOT(AreaID = 5 AND DistrictID = 8)
UNIONed查询似乎也在联合之后重新排序 - 通过选择一个整数(您将用于排序顺序)并给它一个名称来解决这个问题,并将所有内容放在一个子名称中,该子查询按名称排序你的整数。
SELECT * FROM
(
/* UNIONed query goes here */
)
ORDER BY manual_order
有一个问题 - 你必须确保你选择的列具有唯一的名称。如果他们不这样做,那么超级问题会变得混乱。如果需要,可以通过别名列名来解决它。
SELECT ml.ID AS mlID, zc.ID as zcID
AreaID为5且AreaID为0的用户可以对他/她所在区域内跨越多个区域的所有数据进行编辑访问。
你对加入问题的看法是正确的,问题是ml.DistrictID = zc.DistrictID
,如果DistrictID为0会发生什么。反思,我不明白你为什么不加入在MPOOID列上。
如果我向SELECT
添加其他列,也会发生同样的事情
UNION结果会自动进行重复数据删除,因此如果删除不唯一的列,您会发现结果集会缩小...
我是否也可以通过MPOOName在每个小组内订购?
只需将其添加为ORDER BY子句中的辅助列即可。
ORDER BY manual_order, MPOOName
SQLFiddle在http://sqlfiddle.com/#!18/0e442/57
完成不相关,但如果您可以控制数据库设计和5分钟的业余时间,我建议统一表和列名称的大小写。如果您的表名是小写的,那么也使用小写的列名(和下划线来分隔单词),否则使用PascalCase
。每个人都有自己的偏好,对我来说,我更喜欢CAPS for SQL关键字的对比,以及表/列名称的小写。
我假设您的ASP.NET应用程序已经知道 AreaID
和DistrictID
,因此您可能希望使用构建器模式来检查是否DistrictID > 0
,并且仅在返回true时包含额外条件。
districtJoin = '';
districtWhere1 = '';
districtWhere2 = '';
if (mlDistrictID > 0)
{
districtJoin = ' AND ml.DistrictID = zc.DistrictID';
districtWhere = ' AND DistrictID = ' + mlDistrictID.ToString();
}
string queryString =
'SELECT /* ml and zc columns */ FROM MPOO_List ml'
+ ' LEFT JOIN ZIPCodes zc ON ml.AreaID = zc.AreaID' + districtJoin
+ ' WHERE ml.AreaID = ' + mlAreaID.ToString() + districtWhere1
+ ' UNION '
+ ' SELECT /* ml and zc columns */ FROM MPOO_List ml'
+ ' LEFT JOIN ZIPCodes zc ON ml.AreaID = zc.AreaID ' + districtJoin
+ ' WHERE NOT(ml.AreaID = ' + mlAreaID.ToString() + districtWhere + ')';