Объединить UNION и JOIN в запросе SQL - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть следующие Django модели:

class Person(models.Model):
    name = models.CharField(max_length=50)

class Pet(models.Model):
    name = models.CharField(max_length=50)

class Change(models.Model):
    table_name = models.CharField(max_length=50)
    record_id = models.IntegerField()
    workspace_id = models.IntegerField(null=True)

Я могу загрузить некоторые данные в базу данных, используя следующий скрипт:

p1, _ = Person.objects.get_or_create(name="Person1")
_p1, _ = Person.objects.get_or_create(name="Person1.DRAFT")
p2, _ = Person.objects.get_or_create(name="Person2")
_p2, _ = Person.objects.get_or_create(name="Person2.DRAFT")
p3, _ = Person.objects.get_or_create(name="Person3")

t1, _ = Pet.objects.get_or_create(name="Pet1")
t2, _ = Pet.objects.get_or_create(name="Pet2")

c1, _ = Change.objects.get_or_create(table_name="Person", record_id=_p1.pk, workspace_id=1)
c2, _ = Change.objects.get_or_create(table_name="Person", record_id=_p2.pk, workspace_id=2)

Я могу написать запрос, который составляется все строки Person и Pet. Это легко сделать с помощью оператора SQL UNION :

SELECT 'Person' as type, t.id, t.name FROM union_person t
UNION
SELECT 'Pet' as type, t.id, t.name FROM union_pet t;

, который приводит к следующему результату:

| type   | id  | name          |
| :----- | :-- | :------------ |
| Person | 1   | Person1       |
| Person | 2   | Person1.DRAFT |
| Person | 3   | Person2       |
| Person | 4   | Person2.DRAFT |
| Person | 5   | Person3       |
| Pet    | 1   | Pet1          |
| Pet    | 2   | Pet2          |

Теперь моя цель - добавить Столбец workspace_id через JOIN с таблицей Change. Таблица, которую я хочу, должна выглядеть следующим образом (которая в точности совпадает с таблицей выше, только с добавленными значениями workspace_id, если они существуют):

| type   | id  | name          | workspace_id |
| :----- | :-- | :------------ | :----------- |
| Person | 1   | Person1       | NULL         |
| Person | 2   | Person1.DRAFT | 1            |
| Person | 3   | Person2       | NULL         |
| Person | 4   | Person2.DRAFT | 2            |
| Person | 5   | Person3       | NULL         |
| Pet    | 1   | Pet1          | NULL         |
| Pet    | 2   | Pet2          | NULL         |

Это запрос, который я должен выполнить this:

SELECT 'Person' as type, t.id, t.name, c.workspace_id FROM union_person t
LEFT JOIN union_change c on t.id = c.record_id and 'Person' = c.table_name
UNION
SELECT 'Pet' as type, t.id, t.name, c.workspace_id FROM union_pet t
LEFT JOIN union_change c on t.id = c.record_id and 'Pet' = c.table_name;

Это лучшее решение или есть лучшее?

Примечание. Мне нужен этот запрос для создания PostgreSQL представления , который будет использоваться для поиска по всей базе данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...