在SQL Server

时间:2015-07-17 22:33:58

标签: sql sql-server union

我有四个表Table ATable BTable CTable D。所有四个表的模式都是相同的。我需要通过以下方式union这四个表:

  1. 如果Table A中有记录,那么输出表中会考虑该记录。

  2. 如果Table B中有记录,那么只有Table A中没有记录才会在输出表中考虑该记录。

  3. 如果Table C中有记录,则仅在Table ATable B中不存在记录时才会被视为

  4. 如果Table D中有记录,则仅在Table ATable BTable C中不存在记录时才会被视为

  5. 注意 -

    1. 每个表都有一个列,用于标识每个记录的表格本身(我不知道这是否具有任何重要性)

    2. 根据特定列标识记录 - Column X即使在每个表中也不是唯一的

4 个答案:

答案 0 :(得分:1)

你可以做类似的事情(只显示了两个案例,但你应该看看如何扩展它)

WITH CTE1 AS 
(
SELECT 't1' as Source, X, Y
FROM t1
UNION ALL
SELECT 't2' as Source, X, Y
FROM t2
), CTE2 AS
(
SELECT *,
       RANK() OVER (PARTITION BY X 
                    ORDER BY CASE Source 
                               WHEN 't1' THEN 1 
                               WHEN 't2' THEN 2 
                             END) As RN
FROM CTE1
)
SELECT X,Y
FROM CTE2
WHERE RN=1

答案 1 :(得分:0)

我倾向于使用 document.head.insertAdjacentHTML( 'beforeEnd', '<meta name="viewport" content="target-densitydpi=device-dpi,width=device-width,initial-scale=1.0" />' ); $(function(){ //initialization $(".detector").bind("click touchstart",function(e){ $(".detector").removeClass("selected"); $(this).addClass("selected"); unbindLibrary(); bindLibrary($(this).prop("id")); }); //bind library to gesture pad bindLibrary = function(id){ var $pad = $("#gesture-pad"); var events = []; var eventStr = ""; $("#" + id + "List li").each(function(){ events.push($(this).text()); }) //make target event list from each library's gestureList eventStr = events.join(" "); switch(id){ case "hammer": hammer = Hammer($pad.get(0), { prevent_default: true }) .on(eventStr, logEvent); break; case "quojs": for(var i = 0;i<events.length;i++){ $$("#gesture-pad").on(events[i], logEvent); } $$("#gesture-pad").on("touchstart",function(e){ e.preventDefault(); }); break; case "touchSwipe": var options = {}; var touchSwipeHandler = function(name){ if(name.indexOf("pinch") < 0){ return function(event, distance, duration, fingerCount){ var e = {}; e["type"] = name; logEvent(e); }; }else{ return function(e, direction, distance, d, f, pinchZoom){ var e = {}; e["type"] = name; logEvent(e); }; } }; for(var i = 0;i<events.length;i++){ options[events[i]] = new touchSwipeHandler(events[i]); } $pad.swipe(options); break; case "touchy" : var handler = function(name){ return function(event, phase, $target, data){ var e = {}; e["type"] = name; logEvent(e); } } for(var i = 0;i<events.length;i++){ $pad.bind(events[i],new handler(events[i])); } break; } } //unbind library from gesture pad unbindLibrary = function(){ var element = $("#gesture-pad").clone(); $("#gesture-pad").replaceWith(element); $(".gesturelist .selected").removeClass("selected"); } //log detected gesture logEvent = function(e){ $("#detected").text(e.type); var selected = $(".detector.selected").prop("id"); $("#" + selected + "List li").each(function(){ if($(this).text() == e.type){ $(this).addClass("selected"); `enter code here` }; }) return false; } $(".detector").first().addClass("selected"); bindLibrary($(".detector.selected").prop("id")); }) 执行此操作:

not exists

如果每个表中的select a.* from a union all select b.* from b where not exists (select 1 from a where a.x = b.x) union all select c.* from c where not exists (select 1 from a where a.x = c.x) and not exists (select 1 from b where b.x = c.x) union all select d.* from d where not exists (select 1 from a where a.x = d.x) and not exists (select 1 from b where b.x = d.x) and not exists (select 1 from c where c.x = d.x); 列都有索引,那么这应该是最快的方法。

答案 2 :(得分:0)

只要没有NULL列,或者如果优先级较高的表中存在的记录的列为NULL,则可以使用此值,您可以假设同一列在优先级较低的表中为NULL。

SELECT coalesce(a.column1, b.column1, c.column1, d.column1) column1
   ,coalesce(a.column2, b.column2, c.column2, d.column2) column2
   ,coalesce(a.column3, b.column3, c.column3, d.column3) column3
   --...
   ,coalesce(a.columnN, b.columnN, c.columnN, d.columnN) columnN
FROM TableA a
FULL JOIN TableB b on b.ColumnX = a.ColumnX
FULL JOIN TableC c on c.ColumnX = a.ColumnX or c.ColumnX = b.ColumnX
FULL JOIN TableD d on d.ColumnX = a.ColumnX or d.ColumnX = b.ColumnX or d.ColumnX = c.ColumnX

如果NULL值很重要,您可以切换到更复杂(可能更慢)的CASE版本:

CASE WHEN a.columnX IS NOT NULL THEN a.column1
     WHEN b.columnX IS NOT NULL THEN b.column1
     WHEN c.columnX IS NOT NULL THEN c.column1
     WHEN d.columnX IS NOT NULL THEN d.column1 END column1

当然,您可以混合使用,因此不可空的列可以使用以前的语法,而NULL值重要的列使用后者。

希望这样做的目的是修复损坏的模式,并将这些数据全部放在它所属的同一个表中。

答案 3 :(得分:0)

这可能看起来很愚蠢,但是如果你有可能遗漏表格识别栏,你也想要消除重复记录(从一个表格中),那么最简单的答案就是

select <all columns without table identifier> from tableA
union
select <all columns without table identifier> from tableB
union
select <all columns without table identifier> from tableC
...

这正是union的目的:只有在以前不存在行时才添加行。