简体   繁体   English

SQL查询以比较单个表中彼此之间的记录行

[英]SQL Query to compare record rows between each other in single table

I'm trying to work with data in a table that in my opinion is somewhat incomplete and I cannot figure out how to approach this problem or how begin to frame the question to see if what I'm trying to accomplish is even possible using SQL. 我正在尝试使用我认为有些不完整的表中的数据,而且我无法弄清楚如何解决该问题或如何开始构建问题以查看我尝试完成的任务是否甚至可以使用SQL 。 This is a hypothetical representation of the data I'm working with (I entered the data in CSV format since this text field doesn't support table formatting): 这是我正在使用的数据的假设表示(我以CSV格式输入数据,因为此文本字段不支持表格格式):

Date,Time,Traveler,Source,Destination,Travel Status
9/20/2014,1:00pm,James,Station A,Station B,Scheduled
9/20/2014,1:10pm,James,Station A,Station B,Traveling
9/20/2014,1:40pm,James,,Station B,Arrived
9/20/2014,1:00pm,Ann,Station B,Station A,Scheduled
9/20/2014,1:10pm,Ann,Station B,Station A,Traveling
9/20/2014,1:40pm,Ann,,Station A,Arrived
9/20/2014,1:00pm,Karl,Station A,Station B,Scheduled
9/20/2014,1:10pm,Karl,Station A,Station B,Traveling
9/20/2014,1:40pm,Karl,,Station B,Arrived
9/20/2014,1:00pm,Joyce,Station B,Station A,Scheduled
9/20/2014,1:10pm,Joyce,Station B,Station A,Traveling
9/20/2014,1:40pm,Joyce,,Station A,Arrived
9/20/2014,1:00pm,Kelly,Station B,Station B,Scheduled
9/20/2014,1:10pm,Kelly,Station B,Station B,Traveling
9/20/2014,1:40pm,Kelly,,Station B,Arrived
9/20/2014,1:00pm,Sam,Station A,Station A,Scheduled
9/20/2014,1:10pm,Sam,Station A,Station A,Traveling
9/20/2014,1:40pm,Sam,,Station A,Arrived

I'm trying to count how many "types" of arrivals we had, for example how many arrivals of type A->A, how many of type B->B and how many A->B and B->A. 我正在尝试计算到达的“类型”数量,例如,A-> A类型的到达数量,B-> B类型的到达数量以及A-> B和B-> A的数量。

If the data was like this: 如果数据是这样的:

Date,Time,Traveler,Source,Destination,Travel Status
9/20/2014,1:00pm,James,Station A,Station B,Scheduled
9/20/2014,1:10pm,James,Station A,Station B,Traveling
9/20/2014,1:40pm,James,Station A,Station B,Arrived
9/20/2014,1:00pm,Ann,Station B,Station A,Scheduled
9/20/2014,1:10pm,Ann,Station B,Station A,Traveling
9/20/2014,1:40pm,Ann,Station B,Station A,Arrived

this simple query would accomplish this for each type of arrival, ie for type A->B: 这个简单的查询将针对每种到达类型(即对于A-> B类型)完成此操作:

SELECT COUNT(*) FROM TRAVEL_TBL WHERE 
Travel Status = 'Arrived' AND Source = 'Station A'
AND Destination = 'Station B';

But since the Source field is missing from the record that contains the "Arrived" entry, how can I carry out a query to find the counts? 但是,由于包含“已到达”条目的记录中缺少“源”字段,如何执行查询以查找计数? I guess the only way is by comparing each record chronologically somehow for each traveler sequentially and keeping track of when a trip was scheduled by whom and if they arrived and increment the count of this basis. 我想唯一的方法是按顺序对每个旅行者按时间顺序比较每个记录,并跟踪谁安排了一次旅行的时间以及他们是否到达,并增加了此基础的计数。 Is this possible using SQL or can you only accomplish this writing an application in Java, or PHP or whatever host language to carry out the logic? 是否可以使用SQL来实现?还是只能用Java或PHP或任何宿主语言来编写应用程序来完成逻辑?

One solution that works with MS SQL 2012+ is to use the LAG() function to access previous rows: 与MS SQL 2012+配合使用的一种解决方案是使用LAG()函数访问先前的行:

SELECT COUNT(*) AS "Count A-B"
FROM (
    SELECT 
       Date, Time, Traveler, 
       CASE 
          WHEN Source IS NULL THEN LAG(Source,1) OVER (PARTITION BY Date, Traveler ORDER BY Date) 
          ELSE Source 
       END AS Source, 
       Destination, 
       [Travel Status]
from TRAVEL_TBL) derived_table
WHERE [Travel Status] = 'Arrived' AND Source = 'Station A' AND Destination = 'Station B';

Or a more generic version using ROW_NUMBER() (which is a function that should be available in most major databases) in a cte with a self join: 或者在带有自连接的cte中使用ROW_NUMBER()(这是大多数主要数据库中应该使用的功能)的更通用版本:

;WITH cte AS (
    SELECT 
       Date, Time, Traveler, 
       ROW_NUMBER() OVER (ORDER BY Traveler, Date, Time) rn,
       Source,
       Destination, 
       [Travel Status]
    FROM TRAVEL_TBL
) 

SELECT COUNT(*) AS "Count A-B"
FROM (
    SELECT 
       c.Date, c.Time, c.Traveler, 
       CASE 
          WHEN c.Source IS NULL THEN c2.source 
          ELSE c.Source 
       END AS Source,
       c.Destination, 
       c.[Travel Status]
    FROM cte c
    LEFT JOIN cte c2 ON c.rn = c2.rn+1
) derived_table
WHERE [Travel Status] = 'Arrived' AND Source = 'Station A' AND Destination = 'Station B';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM