我有这张桌子:
|ID| GruopID | Status | Date |
| 2| 1 | S1 | 7/29/2011 |
| 3| 1 | S2 | 7/30/2011 |
| 9| 1 | S1 | 8/02/2011 |
| 7| 1 | S1 | 8/03/2011 |
| 8| 1 | S1 | 8/04/2011 |
| 1| 2 | S1 | 7/28/2011 |
| 4| 2 | S2 | 7/30/2011 |
| 5| 2 | S3 | 8/01/2011 |
| 6| 3 | S1 | 8/02/2011 |
以及来自外部来源的具体日期:2011年7月31日
我需要一个查询,它会为每个groupID提供 最接近的上下日期,因此结果将为:
|ID| GruopID | Status | Date |
| 3| 1 | S2 | 7/30/2011 |
| 9| 1 | S1 | 8/02/2011 |
| 4| 2 | S2 | 7/30/2011 |
| 5| 2 | S3 | 8/01/2011 |
| 6| 3 | S1 | 8/02/2011 |
有人可以帮助我并向我显示查询吗?
答案 0 :(得分:1)
直截了当的方法:
SELECT t1.ID, t1.GroupID, t1.Status, t1.Date
FROM MyTable t1
WHERE t1.Date IN (
SELECT MAX(t2.Date)
FROM MyTable t2
WHERE t2.GroupID = t1.GroupID
AND t2.Date <= '7/31/2011'
UNION
SELECT MIN(t3.Date)
FROM MyTable t3
WHERE t3.GroupID = t1.GroupID
AND t3.Date >= '7/31/2011'
)
请注意,每组的行数可能不一定是两行。
答案 1 :(得分:1)
这是一个经典的import sys
from PyQt4 import QtGui, QtCore
class MyDelegate(QtGui.QItemDelegate):
def __init__(self, parent, table):
super(MyDelegate, self).__init__(parent)
self.table = table
def sizeHint(self, option, index):
# Get full viewport size
table_size = self.table.viewport().size()
gw = 1 # Grid line width
rows = self.table.rowCount() or 1
cols = self.table.columnCount() or 1
width = (table_size.width() - (gw * (cols - 1))) / cols
height = (table_size.height() - (gw * (rows - 1))) / rows
return QtCore.QSize(width, height)
class Window(QtGui.QWidget):
def __init__(self, rows, columns):
super(Window, self).__init__()
self.lay = QtGui.QVBoxLayout()
self.setLayout(self.lay)
self.table = QtGui.QTableWidget(rows, columns, self)
self.table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.lay.addWidget(self.table)
self.delegate = MyDelegate(self, self.table)
self.table.setItemDelegate(self.delegate)
def showEvent(self, event):
super(Window, self).showEvent(event)
self.resizeTable()
def resizeTable(self):
self.table.resizeRowsToContents()
self.table.resizeColumnsToContents()
def resizeEvent(self, event):
super(Window, self).resizeEvent(event)
self.resizeTable()
查询。我会在这里使用greatest-n-per-group
。
确保您在CROSS APPLY
上有索引。
您很可能有一个表(GroupID, dt, ID)
,其中包含所有Groups
的列表。在下面的查询中,我使用CTE获取所有不同GroupIDs
的列表。
示例数据
我添加了几行来显示查询在各种情况下的工作方式。
GroupIDs
<强>查询强>
对于每个DECLARE @VarDate date = '2011-07-31';
DECLARE @T TABLE (ID int, GroupID int, Status varchar(2), dt date);
INSERT INTO @T (ID, GroupID, Status, dt) VALUES
(2, 1, 'S1', '2011-07-29'),
(3, 1, 'S2', '2011-07-30'),
(9, 1, 'S1', '2011-08-02'),
(7, 1, 'S1', '2011-08-03'),
(8, 1, 'S1', '2011-08-04'),
(1, 2, 'S1', '2011-07-28'),
(4, 2, 'S2', '2011-07-30'),
(5, 2, 'S3', '2011-08-01'),
(6, 3, 'S1', '2011-08-02'),
(11, 4, 'S1', '2011-08-04'),
(12, 4, 'S2', '2011-08-02'),
(13, 4, 'S3', '2011-08-02'),
(21, 4, 'S1', '2011-07-04'),
(22, 4, 'S2', '2011-07-04'),
(23, 4, 'S3', '2011-07-04'),
(31, 5, 'S1', '2011-07-31'),
(32, 5, 'S2', '2011-07-31'),
(33, 5, 'S3', '2011-07-31'),
(34, 5, 'S1', '2011-07-31'),
(35, 5, 'S2', '2011-07-31'),
(36, 5, 'S3', '2011-07-31'),
(41, 6, 'S1', '2011-07-31');
,我们使用GroupID
找到上排和下排,然后CROSS APPLY
上下结果一起。
UNION ALL
<强>结果强>
WITH
CTE_Groups
AS
(
SELECT DISTINCT GroupID
FROM @T
)
SELECT
CA.ID
,Groups.GroupID
,CA.Status
,CA.dt
FROM
CTE_Groups AS Groups
CROSS APPLY
(
SELECT TOP(1)
T.ID
,T.Status
,T.dt
FROM @T AS T
WHERE
T.GroupID = Groups.GroupID
AND T.dt >= @VarDate
ORDER BY T.dt, ID
) AS CA
UNION ALL
SELECT
CA.ID
,Groups.GroupID
,CA.Status
,CA.dt
FROM
CTE_Groups AS Groups
CROSS APPLY
(
SELECT TOP(1)
T.ID
,T.Status
,T.dt
FROM @T AS T
WHERE
T.GroupID = Groups.GroupID
AND T.dt <= @VarDate
ORDER BY T.dt DESC, ID DESC
) AS CA
ORDER BY GroupID, dt;