Вернуть две строки из таблицы SQL с разницей в значениях

Я пытаюсь вернуть 2 строки из таблицы, которые имеют разницу в значениях, не будучи мудрым человеком SQL, я застрял, любая помощь будет оценена :-)

TABLE A:

NAME    DATA
Oscar   HOME1
Jens    HOME2
Will    HOME1
Jeremy  HOME2
Al      HOME1

Результатом должно быть 2 случайных строки с разницей в значениях DATA.

NAME   DATA
Oscar  HOME1
Jeremy HOME2

Кто-нибудь?


sql
person dahund    schedule 21.06.2016    source источник
comment
Еще лучше, если бы код не требовал статических записей вроде HOME1 ‹› HOME2   -  person dahund    schedule 21.06.2016
comment
Какой у вас РБДМ? SQL Server, Postgres, Oracle?   -  person Juan Carlos Oropeza    schedule 21.06.2016
comment
Должен ли этот вопрос относиться к кодексу гольфа? codegolf.stackexchange.com   -  person ebyrob    schedule 21.06.2016


Ответы (4)


Может быть, тебе нужно

select * from my_table a
inner join my_table b on a.data !=b.data
where a.data in ( SELECT data FROM my_table ORDER BY RAND() LIMIT 1);

Для вашего кода

SELECT * 
FROM [dbo].[ComputerState] as a
INNER JOIN [dbo].[ComputerState] as b ON a.ServiceName != b.ServiceName 
WHERE a.ServiceName IN ( 
     SELECT  top 1  [ServiceName] FROM [dbo].[ComputerState] 
);
person scaisEdge    schedule 21.06.2016
comment
как это возвращает 2 случайные строки? - person devlin carnate; 21.06.2016
comment
@devlincarnate правильно .. я обновил ответ случайными данными - person scaisEdge; 21.06.2016
comment
Это возвращает одну строку с двумя наборами значений в ней. В вопросе запрашиваются значения в двух отдельных строках. - person ebyrob; 21.06.2016
comment
Под внутренней таблицей соединений b вы имеете в виду внутреннюю таблицу соединений a, поскольку это та же таблица = - person dahund; 21.06.2016
comment
под внутренним соединением b я имею в виду внутреннее соединение с той же таблицей .. точно .. в sql таблицы - это таблицы .. такие же или не такие же таблицы .. и вы можете использовать их, как вы явно, в условии .. - person scaisEdge; 21.06.2016
comment
@dahund scaisEdge назвал таблицу table вместо A, как это обозначено в вопросе. Итак, в этом ответе a и b - это просто псевдонимы таблиц в запросе. - person ebyrob; 21.06.2016
comment
@ebyrob правильно .... table a означает a - это псевдоним таблицы .. a.data означает данные столбца таблицы с псевдонимом a - person scaisEdge; 21.06.2016
comment
Итак, это (ВЫБРАТЬ данные ИЗ таблицы ORDER BY RAND () LIMIT 1); что такое таблица? - person dahund; 21.06.2016
comment
ВЫБЕРИТЕ * ИЗ [dbo]. [ComputerState] ВНУТРЕННЕЕ СОЕДИНЕНИЕ [dbo]. [ComputerState] ON [dbo]. [ComputerState] .ServiceName! = [Dbo]. [ComputerState] .ServiceName WHERE [dbo]. [ComputerState] .ServiceName IN (SELECT [ServiceName] FROM [dbo]. [ComputerState] ORDER BY RAND () LIMIT 1) Дает мне неправильный синтаксис рядом с 'LIMIT'. - person dahund; 21.06.2016
comment
@dahund в этом подвыборке нет псевдонима, поэтому таблица является таблицей .. в любом случае я должен изменить ответ. с my_table вместо table .. похоже, вы не знаете псевдоним .. - person scaisEdge; 21.06.2016
comment
Я обновил ответ, установив псевдоним для вашего кода. Надеюсь, полезно - person scaisEdge; 21.06.2016
comment
да, добраться туда :-) теперь выглядит лучше, когда таблицы располагаются рядом друг с другом, но дайте мне этот Неправильный синтаксис рядом с 'LIMIT'. если я добавлю ORDER BY RAND () LIMIT 1, возможно, мне следовало сказать, что это SQL :-) - person dahund; 21.06.2016
comment
ВЫБЕРИТЕ TOP (1) * и удалите LIMIT и порядок - person dahund; 21.06.2016
comment
@dahund да ... это sqlserver, а не mysql .. я обновил ответ - person scaisEdge; 21.06.2016
comment
Отлично, это избавляет меня от большого количества кода C #, мерси :-) - person dahund; 21.06.2016
comment
Эй, еще раз, есть ли шанс, что это может вернуть таблицу в старом порядке? поскольку в моем наборе данных теперь есть строка с [servicename, computername, servicename1, computername1] - person dahund; 23.06.2016
comment
Я предлагаю вам задать новый вопрос, описанный правильно .. таким образом все сообщество может вам помочь .. - person scaisEdge; 23.06.2016

Простой способ получить случайные данные.

;with tblA as (
select name,data,
row_number() over(partition by data order by newid()) rn
from A
)
select name,data
from tblA
where rn = 1
person Alex Kudryashev    schedule 21.06.2016
comment
Разве это не было бы where rn <= 2, поскольку OP хочет 2 строки (или IN (1,2))? - person Igor; 21.06.2016
comment
@ Игорь Нет. См. partition by - person Alex Kudryashev; 21.06.2016
comment
Предполагается, что OP имеет Sql Server. - person Juan Carlos Oropeza; 21.06.2016
comment
Отлично, спасибо. @JuanCarlosOropeza - ИМО, вы должны что-то предполагать, поскольку ОП дает очень мало информации. Если OP требовал решения для конкретного сервера, они должны были включить это в свой вопрос. - person Igor; 21.06.2016
comment
@ Игорь Я могу думать иначе, общее правило, если ты считаешь, что ошибаешься. Так что не тратьте время на неправильный вопрос. Лучше спросите подробности. Очевидно, OP - новый пользователь, поэтому научите его, как лучше задать вопрос. - person Juan Carlos Oropeza; 21.06.2016
comment
Тем не менее, должен быть SELECT TOP 2, потому что раздел находится на данных, а в примере данных, которые будут создавать 3 строки с row_number = 1. Я добавляю, что всегда может быть выбрана одна и та же комбинация данных или предпочтение - person Matt; 21.06.2016
comment
@Matt newid() - очень хороший генератор случайных чисел. ;) - person Alex Kudryashev; 21.06.2016
comment
Я знаю, что это так, и тоже использую это! Я думал, что в столбце данных было 3 разных значения. Но это потому, что я не смотрел на слово data как на имя столбца ... - person Matt; 21.06.2016

Если вопрос действительно настолько прост, вы можете использовать агрегат, такой как MAX() или MIN(), чтобы получить по одной строке для каждого другого DATA:

SELECT   MAX(NAME), DATA
FROM     TABLE_A
GROUP BY DATA

Конечно, если в требования ввести какие-либо другие переменные, это может больше не работать.

person Aaron Dietz    schedule 21.06.2016
comment
как это случайно? - person devlin carnate; 21.06.2016
comment
@devlincarnate Хороший момент, я прочитал верхнюю часть, сосредоточившись на том, чтобы просто иметь разные значения DATA. Если он должен быть действительно случайным, это не сработает. - person Aaron Dietz; 21.06.2016
comment
Столбец "DATA" недопустим в списке выбора, поскольку он не содержится ни в агрегатной функции, ни в предложении GROUP BY. ты знаешь что это? - person dahund; 21.06.2016
comment
@dahund DATA прямо здесь: GROUP BY DATA - person ebyrob; 21.06.2016

;WITH cteA AS (
    SELECT
       name
       ,data
       ,ROW_NUMBER() OVER (PARTITION BY data ORDER BY NEWID()) as DataRowNumber
       ,ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY NEWID()) as RandomRowNumber
    FROM
       A
)

SELECT *
FROM
    cteA
WHERe
    DataRowNumber = 1
    AND RandomRowNumber <= 2

Это немного расширяется в ответе @AlexKudryashev.

;with tblA as (
select name,data,
row_number() over(partition by data order by newid()) rn
from A
)
select name,data
from tblA
where rn = 1

Единственная проблема с тем, что у него было, это то, что количество строк, где rn = 1 будет зависеть от COUNT(DISTINCT data), так что это может привести к более чем двум результатам. Чтобы исправить это, можно добавить предложение SELECT TOP 2, но оно может быть не полностью случайным, поскольку результаты в этот момент будут зависеть от порядковых результатов того, как SQL оптимизирует запрос, который, вероятно, будет согласованным. Чтобы получить действительно случайный результат, добавьте второй случайный номер строки и ограничьте результаты двумя верхними из них.

person Matt    schedule 21.06.2016