Объедините две таблицы, у которых нет общих полей
Я хочу узнать, как объединить две таблицы БД, которые не имеют общих полей. Я проверил UNION, но MSDN говорит:
Ниже приведены основные правила объединения наборов результатов двух запросов с помощью UNION:
- Количество и порядок столбцов должны быть одинаковыми во всех запросах.
- Типы данных должны быть совместимы.
Но у меня нет общих полей вообще. Все, что я хочу, это объединить их в одну таблицу, как представление.
И что же мне делать?
Ответы
Ответ 1
Существует несколько способов сделать это, в зависимости от того, что вы действительно хотите. Без общих столбцов вам нужно решить, хотите ли вы ввести общий столбец или получить продукт.
Скажем, у вас есть две таблицы:
parts: custs:
+----+----------+ +-----+------+
| id | desc | | id | name |
+----+----------+ +-----+------+
| 1 | Sprocket | | 100 | Bob |
| 2 | Flange | | 101 | Paul |
+----+----------+ +-----+------+
Забудьте о фактических столбцах, поскольку в этом случае у вас, скорее всего, будет соотношение клиент/заказ/часть; Я просто использовал эти столбцы, чтобы проиллюстрировать, как это сделать.
Декартово произведение будет соответствовать каждой строке в первой таблице с каждой строкой во втором:
> select * from parts, custs;
id desc id name
-- ---- --- ----
1 Sprocket 101 Bob
1 Sprocket 102 Paul
2 Flange 101 Bob
2 Flange 102 Paul
Вероятно, это не то, что вы хотите, так как 1000 частей и 100 клиентов приведут к 100 000 строк с большим количеством дублированной информации.
В качестве альтернативы вы можете использовать объединение, чтобы просто выводить данные, но не бок о бок (вам нужно убедиться, что типы столбцов совместимы между двумя выборками, либо путем согласования столбцов таблицы или их принудительного использования в выборе):
> select id as pid, desc, '' as cid, '' as name from parts
union
select '' as pid, '' as desc, id as cid, name from custs;
pid desc cid name
--- ---- --- ----
101 Bob
102 Paul
1 Sprocket
2 Flange
В некоторых базах данных вы можете использовать столбец rowid/rownum или псевдо-столбец для сопоставления записей бок о бок, например:
id desc id name
-- ---- --- ----
1 Sprocket 101 Bob
2 Flange 101 Bob
Код будет выглядеть примерно так:
select a.id, a.desc, b.id, b.name
from parts a, custs b
where a.rownum = b.rownum;
Он по-прежнему является декартовым продуктом, но предложение where
ограничивает, как строки объединяются, чтобы сформировать результаты (а значит, и не декартово произведение вообще).
Я не тестировал этот SQL для этого, так как это одно из ограничений моей СУБД выбора, и это справедливо, я не верю, что это когда-либо понадобилось в продуманной схеме. Поскольку SQL не гарантирует порядок, в котором он производит данные, соответствие может изменяться каждый раз, когда вы выполняете запрос, если у вас нет конкретной связи или order by
.
Я думаю, что идеальной задачей было бы добавить столбец в обе таблицы, указав, какова связь. Если нет реальных отношений, то вы, вероятно, не имеете дело с попыткой поставить их бок о бок с SQL.
Если вы просто хотите, чтобы они отображались бок о бок в отчете или на веб-странице (два примера), правильным инструментом для этого является то, что генерирует ваш отчет или веб-страницу в сочетании с двумя независимыми SQL-запросами две несвязанные таблицы. Например, сетка с двумя столбцами в BIRT (или Crystal или Jasper), каждая с отдельной таблицей данных, или таблица с двумя столбцами (или CSS) HTML, каждая с отдельной таблицей данных.
Ответ 2
Это очень странная просьба и почти наверняка то, что вы никогда не захотите делать в реальном приложении, но с чисто академической точки зрения это интересная задача. С SQL Server 2005 вы можете использовать общие выражения таблиц и функции row_number() и присоединяться к этому:
with OrderedFoos as (
select row_number() over (order by FooName) RowNum, *
from Foos (nolock)
),
OrderedBars as (
select row_number() over (order by BarName) RowNum, *
from Bars (nolock)
)
select *
from OrderedFoos f
full outer join OrderedBars u on u.RowNum = f.RowNum
Это работает, но это в высшей степени глупо, и я предлагаю его только как ответ "сообщество вики", потому что я действительно не рекомендую его.
Ответ 3
SELECT *
FROM table1, table2
Это объединит каждую строку таблицы1 с таблицей2 (декартово произведение), возвращающим все столбцы.
Ответ 4
Если в таблицах нет общих полей, нет возможности объединить данные в любом значимом представлении. Скорее всего, вы получите представление, содержащее дублированные данные из обеих таблиц.
Ответ 5
попробовать:
select * from table 1 left join table2 as t on 1 = 1;
Это приведет ко всем столбцам из таблицы.
Ответ 6
Чтобы получить осмысленный/полезный вид двух таблиц, вам обычно необходимо определить поле идентификации из каждой таблицы, которое затем можно использовать в предложении ON в JOIN.
THEN на ваш взгляд:
SELECT T1.*, T2.* FROM T1 JOIN T2 ON T1.IDFIELD1 = T2.IDFIELD2
Вы упомянули, что никакие поля не являются "общими", но хотя идентифицирующие поля могут не иметь одинакового имени или даже быть одним и тем же типом данных, вы можете использовать функции convert/cast, чтобы каким-то образом связать их.
Ответ 7
почему вы не используете простой подход
SELECT distinct *
FROM
SUPPLIER full join
CUSTOMER on (
CUSTOMER.OID = SUPPLIER.OID
)
Он дает вам все столбцы из обеих таблиц и возвращает все записи от клиента и поставщика, если у Клиента есть 3 записи, а поставщик имеет 2, тогда поставщик будет показывать NULL во всех столбцах.
Ответ 8
select
status_id,
status,
null as path,
null as Description
from
zmw_t_status
union
select
null,
null,
path as cid,
Description from zmw_t_path;
Ответ 9
Select
DISTINCT t1.col,t2col
From table1 t1, table2 t2
OR
Select
DISTINCT t1.col,t2col
From table1 t1
cross JOIN table2 t2
если его объявить данные, это займет много времени.
Ответ 10
SELECT t1.col table1col, t2.col table2col
FROM table1 t1
JOIN table2 t2 on t1.table1Id = x and t2.table2Id = y
Ответ 11
select * from this_table;
select distinct person from this_table
union select address as location from that_table
drop wrong_table from this_database;
Ответ 12
Очень тяжело, когда приходится делать это с тремя выбранными утверждениями
Я попробовал все предложенные методы там, но это напрасно
Пожалуйста, смотрите ниже сценарий. пожалуйста, совет, если у вас есть альтернативное решение
select distinct x.best_Achiver_ever,y.Today_best_Achiver ,z.Most_Violator from
(SELECT Top(4) ROW_NUMBER() over (order by tl.username) AS conj, tl.
[username] + '-->' + str(count(*)) as best_Achiver_ever
FROM[TiketFollowup].[dbo].N_FCR_Tikect_Log_Archive tl
group by tl.username
order by count(*) desc) x
left outer join
(SELECT
Top(4) ROW_NUMBER() over (order by tl.username) as conj, tl.[username] + '-->' + str(count(*)) as Today_best_Achiver
FROM[TiketFollowup].[dbo].[N_FCR_Tikect_Log] tl
where convert(date, tl.stamp, 121) = convert(date,GETDATE(),121)
group by tl.username
order by count(*) desc) y
on x.conj=y.conj
left outer join
(
select ROW_NUMBER() over (order by count(*)) as conj,username+ '--> ' + str( count(dbo.IsViolated(stamp))) as Most_Violator from N_FCR_Ticket
where dbo.IsViolated(stamp) = 'violated' and convert(date,stamp, 121) < convert(date,GETDATE(),121)
group by username
order by count(*) desc) z
on x.conj = z.conj
Ответ 13
Попробуйте этот запрос:
Объедините две таблицы, которые не имеют общих столбцов:
SELECT *
FROM table1
UNION
SELECT *
FROM table2
ORDER BY orderby ASC