【问题标题】:Looping distinct values from one table through another without a join在没有连接的情况下将一个表中的不同值循环到另一个表
【发布时间】:2015-09-08 07:37:28
【问题描述】:

我知道循环在 SQL 中并不理想,但我想不出另一种方法。

我希望此表 1 中的每个不同行在表 2 中生成每个不同的日期和时间。

换句话说,表 2 的日期介于 2014 年 5 月 1 日到 2015 年 4 月 30 日之间,每个不同的日期有 24 行,一天中的每个小时一个。我现在希望表 1 中的每个不同行在表 2 中都有每个不同的日期,每个日期都是 24 小时。

表 1:

DROP TABLE Baylor_Raw..MEDICAL_SERVICE_DESC
SELECT MEDICAL_SERVICE_DESC 
INTO Baylor_Raw..MEDICAL_SERVICE_DESC
FROM Baylor_Raw..Raw_ADT 
WHERE MEDICAL_SERVICE_DESC IS NOT NULL AND MEDICAL_SERVICE_DESC NOT IN ('#N/A','CANCEL','DAY SURGERY','HOSPICE','INFUSION')

表 2:

DECLARE @DATE DATE
SET @DATE = '05/01/2014'

DECLARE @HOUR INT
SET @HOUR = 0

DROP TABLE Baylor_Raw..DateTable
CREATE TABLE Baylor_Raw..DateTable
    (DATE_OF_DISCHARGE DATE
    ,HOUR_OF_DISCHARGE INT)


WHILE @DATE<'05/01/2015' BEGIN
    WHILE @HOUR<25 BEGIN
        INSERT INTO Baylor_Raw..DateTable (DATE_OF_DISCHARGE,HOUR_OF_DISCHARGE)
        VALUES (@DATE,@HOUR)
        SET @HOUR = @HOUR+1
    END
    SET @DATE = DATEADD(DD,1,@DATE)
    SET @HOUR = 0
END

以下尝试无效。运行时间超过几分钟后我取消了。

DECLARE @MEDICAL_SERVICE_DESC NVARCHAR(255)
SET @MEDICAL_SERVICE_DESC = (SELECT MIN(MEDICAL_SERVICE_DESC) FROM Baylor_Raw..MEDICAL_SERVICE_DESC)

DECLARE @DATE DATE
SET @DATE = '05/01/2014'

DECLARE @HOUR INT
SET @HOUR = 0

DROP TABLE Baylor_Raw..DateTable
CREATE TABLE Baylor_Raw..DateTable
(MEDICAL_SERVICE_DESC NVARCHAR,
DATE_OF_DISCHARGE DATE
,HOUR_OF_DISCHARGE INT)

WHILE @MEDICAL_SERVICE_DESC IS NOT NULL BEGIN
    WHILE @DATE<'05/01/2015' BEGIN
        WHILE @HOUR<25 BEGIN
            INSERT INTO Baylor_Raw..DateTable (MEDICAL_SERVICE_DESC,DATE_OF_DISCHARGE,HOUR_OF_DISCHARGE)
            VALUES (@MEDICAL_SERVICE_DESC,@DATE,@HOUR)
            SET @HOUR = @HOUR+1
        END
        SET @DATE = DATEADD(DD,1,@DATE)
        SET @HOUR = 0
    END
DELETE FROM Baylor_Raw..MEDICAL_SERVICE_DESC WHERE MEDICAL_SERVICE_DESC = @MEDICAL_SERVICE_DESC
SET @MEDICAL_SERVICE_DESC = (SELECT MIN(MEDICAL_SERVICE_DESC) FROM Baylor_Raw..MEDICAL_SERVICE_DESC)
SET @DATE = '05/01/2014'
END

【问题讨论】:

  • 我现在就告诉你,我认为你没有正确处理这个问题。试着用文字解释你想要达到的目标,比如这些表格到底是做什么用的?然后用样本数据提供一些基本的输入和输出。我敢打赌有一种更简单的方法可以做到这一点而无需循环。
  • 我同意。但是,我只需要创建一次这个表,这就是为什么我认为使用循环就足够了。
  • 哦,这还不错。好吧,我很高兴 thorsten 回答了你的问题!

标签: sql sql-server tsql while-loop


【解决方案1】:

所以您希望 table1 中的所有不同记录与 table2 中的所有记录配对?那是交叉连接:

select *
from (select distinct * from table1) t1
cross join table2;

或者您希望它们按日期关联?然后内连接:

select *
from (select distinct * from table1) t1
inner join table2 t2 on t1.date = t2.date;

【讨论】:

    【解决方案2】:

    首先使用循环构建日期和小时列表,然后使用交叉连接将其与服务名称组合一次,您可能会获得更好的性能,就像这样。您可能需要稍微调整一下,因为您了解源数据:

    DECLARE @dates TABLE (DATE DATE)
    DECLARE @hours TABLE (hours INT)
    DECLARE @hour INT
        ,@date DATE
    
    SET @hour = 0
    SET @date = '05/01/2014'
    
    WHILE (@hour < 25)
    BEGIN
        INSERT INTO @hours
        SELECT @hour
    
        SET @hour = @hour + 1
    END
    
    WHILE (@ DATE < '05/01/2015')
    BEGIN
        INSERT INTO @dates
        SELECT @date
    
        SET @DATE = DATEADD(DD, 1, @DATE)
    END
    
    INSERT INTO Baylor_Raw..DateTable (
        MEDICAL_SERVICE_DESC
        ,DATE_OF_DISCHARGE
        ,HOUR_OF_DISCHARGE
        )
    SELECT MEDICAL_SERVICE_DESC
        ,DATE
        ,hour
    FROM Baylor_Raw..MEDICAL_SERVICE_DESC
    CROSS JOIN @date d
    CROSS JOIN @hours h
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-13
      • 1970-01-01
      • 1970-01-01
      • 2011-03-16
      • 2012-09-17
      • 2021-03-28
      相关资源
      最近更新 更多