SQL Server查询语句 [英] SQL Server Query statement

查看:77
本文介绍了SQL Server查询语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨专家,



我在SQL Server表'tblLeave'中有一些如下数据: -



 PAYCODE LV_TYPE FROM_DATE TO_DATE LVALUE 
5023 SL 14/12/2012 0:00 14/12/2012 0:00 1
5023 SL 15/12 / 2012 0:00 15/12/2012 0:00 1
5023 COF 16/12/2012 0:00 16/12/2012 0:00 1
5023 SL 19/12/2012 0: 00 19/12/2012 0:00 1
5023 SL 22/12/2012 0:00 22/12/2012 0:00 1
5023 SL 23/12/2012 0:00 23/12 / 2012 0:00 1
5023 SL 24/12/2012 0:00 24/12/2012 0:00 1
5023 PL 28/12/2012 0:00 28/12/2012 0: 00 1
5023 PL 29/12/2012 0:00 29/12/2012 0:00 1
5023 PL 30/12/2012 0:00 30/12/2012 0:00 1
5023 PL 31/12/2012 0:00 31/12/2012 0:00 1





查询结果必须如下: -



 PAYCODE LV_TYPE FROM_DATE TO_DATE LVALUE 
5023 SL 14/12/2012 0:00 15/12/2012 0:00 2
5023 COF 16/12 / 2012 0:00 16/12/2012 0:00 1
5023 SL 19/12/2012 0:00 19/12/2012 0:00 1
5023 SL 22/12/2012 0:00 24/12/2012 0:00 3
5023 PL 28/12/2012 0:00 31/12/2012 0:00 4





如果连续休假相同,则应合并为一行,提及from_date至to_date。



请帮帮我。



谢谢,



Anil Kumar



添加了代码块 - OriginalGriff [/ edit]

解决方案

检查一下。

   SELECT  LV_TYPE,LV_TYPE,MIN(FROM_DATE) AS  FROM_DATE,MAX(TO_DATE) AS  TO_DATE,COUNT(LVALUEP) AS  LVALUE 
FROM tblLeave
GROUP BY PAYCODE,LV_TYPE



请尝试以下

  SELECT  PAYCODE,LV_TYPE,MIN( FROM_DATE) AS  FROM_DATE,
MAX(FROM_DATE) AS TO_DATE,COUNT(' A' AS LVALUE
FROM
SELECT PAYCODE,LV_TYPE,FROM_DATE,
DATEDIFF(D,ROW_NUMBER() OVER ORDER BY FROM_DATE),FROM_DATE ) AS DtRange
FROM tblLeave) AS dt
GROUP BY PAYCODE,LV_TYPE,DtRange
ORDER BY FROM _DATE



 PAYCODE LV_TYPE FROM_DATE TO_DATE LVALUE 
----------- ------ - ---------- ---------- -----------
5023 SL 2012-12-14 2012-12-15 2
5023 COF 2012-12-16 2012-12-16 1
5023 SL 2012-12-19 2012-12-19 1
5023 SL 2012-12-22 2012-12-24 3
5023 PL 2012-12-28 2012-12-31 4


我测试了解决方案1并且它不返回您需要的结果集。



下面的存储过程已经过测试,并返回您在示例中显示的结果集。在SQL Server数据库中创建此存储过程并在程序中执行存储过程。存储过程将返回行,如示例中所示。



可能会有一些奇特的SQL语句会返回相同的结果,但我无法弄明白。我通读了我的 Jim Celko的SQL for Smarties 一书,这种类型的查询不在那里。我欢迎其他可能比我更了解SQL的贡献者提交一个在单个SQL语句而不是存储过程算法中完成的解决方案。



 USE [YourDatabaseNameGoesHere] 
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
- ========= ====================================
- 作者:Mike Meinz
- 创建日期:2013年1月26日
- 描述:总结离开行
- ========================= ====================
CREATE PROCEDURE SUMMARIZE_LEAVE_ROWS
AS
BEGIN
- 添加SET NOCOUNT ON以防止额外的来自
的结果集 - 干扰SELECT语句。
SET NOCOUNT ON;
DECLARE @curPayCode int,@ curLV_Type varchar(3),@ curFrom_Date date,@ curTo_Date date,@ curLValue int
DECLARE @lastPayCode int,@ lastLV_Type varchar(3),@ lastFrom_Date date,@ lastTo_Date date ,@ lastLValue int
DECLARE @SummarizedRowsTable TABLE(PayCode int,LV_Type varchar(3),From_date date,To_Date date,lvalue int)
-
- 从tblLeave $ b $中选择行b声明Summary_Leave_Cursor CURSOR FOR
SELECT PayCode,LV_Type,From_Date,To_Date,lvalue from tblLeave order by PayCode,From_date,LV_Type
DECLARE @FIRST_TIME BIT
SET @ FIRST_TIME = 1
OPEN Summary_Leave_Cursor
- 获取第一行
FETCH NEXT FROM Summary_Leave_Cursor INTO @ curPayCode,@ curLV_Type,@ curFrom_date,@ curTo_Date,@ curLValue
WHILE @@ FETCH_STATUS = 0
BEGIN
IF @ FIRST_TIME = 1
BEGIN
SET @ FIRST_TIME = 0
- 保存当前行数据
SET @ lastPayCode = @ curPayCode
SET @ lastLV_Type = @curLV_Type
SET @ lastFrom_Date = @ curFrom_Date
SET @lastTo_ Date = @ curTo_Date
SET @ lastLValue = @ curLValue
END
ELSE
BEGIN
- 检查相同的PayCode和离开类型以及当前的FromDate是否晚于最后ToDate
- 使用DATEDIFF和DATEADD比较日期
- 如果需要考虑时间,则必须更改
IF @ curPayCode = @ lastPayCode AND @ curLV_Type = @ lastLV_Type AND DATEDIFF(day,@ CurFrom_date,DATEADD(day,1,@ lastTo_date))= 0
BEGIN
- 累积LValue
SET @ lastlvalue = @ lastlvalue + @ curlvalue
- 使用新的ToDate更新ToDate
SET @ lastTo_Date = @ curTo_Date
END
ELSE
BEGIN
- 将汇总数据插入到临时表
INSERT INTO @SummarizedRowsTable(PayCode,LV_Type,From_Date,To_Date,lvalue)值(@lastPayCode,@ lastLV_Type,@ lastFrom_Date,@ lastTo_Date,@ lastLValue);
- 保存当前行数据
SET @ lastPayCode = @ curPayCode
SET @ lastLV_Type = @ curLV_Type
SET @ lastFrom_Date = @ curFrom_Date
SET @ lastTo_Date = @ curTo_Date
SET @ lastLValue = @ curLValue
END
END
FETCH NEXT FROM Summary_Leave_Cursor INTO @ curPayCode,@ curLV_Type,@ curFrom_date,@ curTo_Date,@ curLValue;
END
- 将最后一个汇总行插入临时表
INSERT INTO @SummarizedRowsTable(PayCode,LV_Type,From_Date,To_Date,lvalue)值(@lastPayCode,@ lastLV_Type,@ lastFrom_Date, @ lastTo_Date,@ lastLValue);
关闭Summary_Leave_Cursor;
DEALLOCATE Summary_Leave_Cursor;
-
- 返回临时表作为存储过程结果
SELECT PayCode,LV_Type,From_Date,To_Date,Lvalue FROM @SummarizedRowsTable order by PayCode,From_Date,LV_Type;
结束





这是我用来测试存储过程的表设计:

 CREATE TABLE [dbo]。[tblLeave](
[PayCode] [int] NOT NULL,
[LV_Type] [varchar](3)NOT NULL,
[ From_date] [date] NOT NULL,
[To_Date] [date] NOT NULL,
[LValue] [int] NOT NULL
)ON [PRIMARY]


Hi Experts,

I have some data like below in SQL Server Table ''tblLeave'': -

PAYCODE	LV_TYPE	FROM_DATE	TO_DATE	        LVALUE
5023	SL    	14/12/2012 0:00	14/12/2012 0:00	1
5023	SL    	15/12/2012 0:00	15/12/2012 0:00	1
5023	COF   	16/12/2012 0:00	16/12/2012 0:00	1
5023	SL    	19/12/2012 0:00	19/12/2012 0:00	1
5023	SL    	22/12/2012 0:00	22/12/2012 0:00	1
5023	SL    	23/12/2012 0:00	23/12/2012 0:00	1
5023	SL    	24/12/2012 0:00	24/12/2012 0:00	1
5023	PL    	28/12/2012 0:00	28/12/2012 0:00	1
5023	PL    	29/12/2012 0:00	29/12/2012 0:00	1
5023	PL    	30/12/2012 0:00	30/12/2012 0:00	1
5023	PL    	31/12/2012 0:00	31/12/2012 0:00	1



Query result must be as below: -

PAYCODE LV_TYPE FROM_DATE       TO_DATE         LVALUE
5023    SL      14/12/2012 0:00 15/12/2012 0:00 2
5023    COF     16/12/2012 0:00 16/12/2012 0:00 1
5023    SL      19/12/2012 0:00 19/12/2012 0:00 1
5023    SL      22/12/2012 0:00 24/12/2012 0:00 3
5023    PL      28/12/2012 0:00 31/12/2012 0:00 4



If same type of leave taken continously,it shoul be merged in one row mentioning from_date to to_date.

Please help me.

Thanks,

Anil Kumar

[edit]Code block added - OriginalGriff[/edit]

解决方案

Check this.

SELECT LV_TYPE,LV_TYPE,MIN(FROM_DATE) AS FROM_DATE ,MAX(TO_DATE) AS TO_DATE, COUNT(LVALUEP) AS LVALUE
 FROM tblLeave
GROUP BY PAYCODE,LV_TYPE


Please try following

SELECT PAYCODE,LV_TYPE, MIN(FROM_DATE) AS FROM_DATE,
       MAX(FROM_DATE) AS TO_DATE, COUNT('A') AS LVALUE
FROM (
SELECT PAYCODE,LV_TYPE,FROM_DATE,
    DATEDIFF(D, ROW_NUMBER() OVER(ORDER BY FROM_DATE), FROM_DATE) AS DtRange
FROM tblLeave) AS dt
GROUP BY PAYCODE,LV_TYPE,DtRange
ORDER BY FROM_DATE


PAYCODE     LV_TYPE FROM_DATE  TO_DATE    LVALUE
----------- ------- ---------- ---------- -----------
5023        SL      2012-12-14 2012-12-15 2
5023        COF     2012-12-16 2012-12-16 1
5023        SL      2012-12-19 2012-12-19 1
5023        SL      2012-12-22 2012-12-24 3
5023        PL      2012-12-28 2012-12-31 4


I tested Solution 1 and it does not return the result set that you required.

The Stored Procedure below has been tested and returns the result set that you showed in your example. Create this Stored Procedure in your SQL Server database and execute the Stored Procedure in your program. The Stored Procedure will return the rows as shown in your example.

There may be some fancy SQL statement that will return the same result but I wasn''t able to figure it out. I read through my Jim Celko''s SQL for Smarties book and this type of query was not in there. I welcome other contributors that may know SQL better than I to submit a solution that is done in a single SQL statement rather than a Stored Procedure algorithm.

USE [YourDatabaseNameGoesHere]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:	Mike Meinz
-- Create date: 26 January 2013
-- Description:	Summarizes Leave Rows
-- =============================================
CREATE PROCEDURE SUMMARIZE_LEAVE_ROWS
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @curPayCode int,@curLV_Type varchar(3),@curFrom_Date date,@curTo_Date date,@curLValue int
DECLARE @lastPayCode int,@lastLV_Type varchar(3),@lastFrom_Date date,@lastTo_Date date,@lastLValue int
DECLARE @SummarizedRowsTable TABLE (PayCode int,LV_Type varchar(3),From_date date,To_Date date,lvalue int) 
-- 
-- Select rows from tblLeave
Declare Summary_Leave_Cursor CURSOR FOR
	SELECT PayCode,LV_Type,From_Date,To_Date,lvalue from tblLeave order by PayCode, From_date, LV_Type
DECLARE @FIRST_TIME BIT
SET @FIRST_TIME=1
OPEN Summary_Leave_Cursor
-- Get first row
FETCH NEXT FROM Summary_Leave_Cursor INTO @curPayCode,@curLV_Type,@curFrom_date,@curTo_Date,@curLValue
WHILE @@FETCH_STATUS = 0
BEGIN
	IF @FIRST_TIME=1
		BEGIN
		SET @FIRST_TIME=0
		-- Save the current row data 
		SET @lastPayCode=@curPayCode
		SET @lastLV_Type=@curLV_Type
		SET @lastFrom_Date=@curFrom_Date
		SET @lastTo_Date=@curTo_Date
		SET @lastLValue=@curLValue
		END
	ELSE
		BEGIN
		-- Check if same PayCode and leave type and current FromDate is one day later than last ToDate
		-- Use DATEDIFF and DATEADD to compare the dates
		-- If times need to be taken into consideration, then this will have to be changed
		IF @curPayCode=@lastPayCode AND @curLV_Type=@lastLV_Type AND DATEDIFF(day,@CurFrom_date,DATEADD(day,1,@lastTo_date))=0 
			BEGIN
			-- Accumulate the LValue
			SET @lastlvalue=@lastlvalue + @curlvalue
			-- Update the ToDate with the new ToDate
			SET @lastTo_Date=@curTo_Date
			END
		ELSE
			BEGIN
			-- Insert summarized data into the temporary table
			INSERT INTO @SummarizedRowsTable (PayCode,LV_Type,From_Date,To_Date,lvalue) Values (@lastPayCode, @lastLV_Type, @lastFrom_Date,@lastTo_Date,@lastLValue);
			-- Save the current row data 
			SET @lastPayCode=@curPayCode
			SET @lastLV_Type=@curLV_Type
			SET @lastFrom_Date=@curFrom_Date
			SET @lastTo_Date=@curTo_Date
			SET @lastLValue=@curLValue
			END
		END
	FETCH NEXT FROM Summary_Leave_Cursor INTO @curPayCode,@curLV_Type,@curFrom_date,@curTo_Date,@curLValue;
END
-- Insert the last summarized row into the temporary table
INSERT INTO @SummarizedRowsTable (PayCode,LV_Type,From_Date,To_Date,lvalue) Values (@lastPayCode, @lastLV_Type, @lastFrom_Date,@lastTo_Date,@lastLValue);
CLOSE Summary_Leave_Cursor;
DEALLOCATE Summary_Leave_Cursor;
--
-- Return the temporary table as the stored procedure result
SELECT PayCode,LV_Type,From_Date,To_Date,lvalue FROM @SummarizedRowsTable order by PayCode, From_Date, LV_Type;
END



This is the table design that I used to test the Stored Procedure:

CREATE TABLE [dbo].[tblLeave](
	[PayCode] [int] NOT NULL,
	[LV_Type] [varchar](3) NOT NULL,
	[From_date] [date] NOT NULL,
	[To_Date] [date] NOT NULL,
	[LValue] [int] NOT NULL
) ON [PRIMARY]


这篇关于SQL Server查询语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆