Sql选择查询 - 如何根据ID进行排序

时间:2018-04-21 04:35:37

标签: sql-server-2008

我试图选择记录并使用特定列的值对其进行排序。

将用户分配到特定区域或区域(与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位于顶部。

1 个答案:

答案 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应用程序已经知道AreaIDDistrictID,因此您可能希望使用构建器模式来检查是否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 + ')';