ცხრილების დაკავშირება დამაკავშირებელი ცხრილის მეშვეობით Python-ში
დავუშვათ, რომ მომხმარებელი იყო სხვადასხვა ქალაქში. ამ შემთხვევაში, მომხმარებლების ცხრილს შეიძლება ჰქონდეს შემდეგი სახე:
| id | name | city |
|---|---|---|
| 1 | user1 | city1, city2, city3 |
| 2 | user2 | city1, city2 |
| 3 | user3 | city2, city3 |
| 4 | user4 | city1 |
გასაგებია, რომ მონაცემების ასე შენახვა არასწორია - ქალაქები უნდა გამოვყოთ ცალკე ცხრილში. აი ის:
| id | name |
|---|---|
| 1 | city1 |
| 2 | city2 |
| 3 | city3 |
თუმცა, ჩვენ გვსურს, რომ თითოეულ მომხმარებელს შეეძლოს რამდენიმე ქალაქზე მითითება. ამის გაკეთება ორი ცხრილის საშუალებით შეუძლებელია.
ჩვენ გვჭირდება ე.წ. დამაკავშირებელი ცხრილის შემოღება, რომელიც დააკავშირებს მომხმარებელს მის ქალაქებთან.
ამ ცხრილის თითოეულ ჩანაწერში შეინახება კავშირი მომხმარებელსა და ერთ ქალაქს შორის. ამ შემთხვევაში, ერთი მომხმარებლისთვის ამ ცხრილში იქნება იმდენი ჩანაწერი, რამდენ ქალაქშიც ის იმყოფებოდა.
აი ჩვენი დამაკავშირებელი ცხრილი:
| id | user_id | city_id |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 1 |
| 5 | 2 | 2 |
| 6 | 3 | 2 |
| 7 | 3 | 3 |
| 8 | 4 | 1 |
მომხმარებლების ცხრილი შეინახავს მხოლოდ მომხმარებლების სახელებს, კავშირების გარეშე:
| id | name |
|---|---|
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
| 4 | user4 |
| 5 | user5 |
მოთხოვნები
მოდით შევქმნათ მოთხოვნა, რომლის საშუალებითაც ამოვიღებთ მომხმარებლებს მათ ქალაქებთან ერთად. ამისთვის დაგვჭირდება ორი join-ის გაკეთება: პირველი join დააკავშირებს მომხმარებლებს დამაკავშირებელ ცხრილთან, ხოლო მეორე join კავშირების მეშვეობით დააკავშირებს ქალაქებს:
SELECT
users.name as user_name, cities.name as city_name
FROM
users
LEFT JOIN users_cities ON users_cities.user_id=users.id
LEFT JOIN cities ON users_cities.city_id=cities.id
მოთხოვნის შედეგი
ჩვენი მოთხოვნის შედეგი Python-ში შეიცავს თითოეული მომხმარებლის სახელს იმდენჯერ, რამდენ ქალაქთანაც არის ის დაკავშირებული:
{'user_name': 'user1', 'city_name': 'city1'}
{'user_name': 'user1', 'city_name': 'city2'}
{'user_name': 'user1', 'city_name': 'city3'}
{'user_name': 'user2', 'city_name': 'city1'}
{'user_name': 'user2', 'city_name': 'city2'}
{'user_name': 'user3', 'city_name': 'city2'}
{'user_name': 'user3', 'city_name': 'city3'}
{'user_name': 'user4', 'city_name': 'city1'}
{'user_name': 'user5', 'city_name': None}
უფრო მოსახერხებელი იქნებოდა ასეთი ლექსიკონის კონვერტაცია და მისი გარდაქმნა შემდეგში:
{
'user1': ['city1', 'city2', 'city3'],
'user2': ['city1', 'city2'],
'user3': ['city2', 'city3'],
'user4': ['city1'],
'user5': []
}
დავწეროთ კოდი, რომელიც ასეთ კონვერტაციას ასრულებს.
შევქმნათ ცარიელი ლექსიკონი user_cities_dct,
რომელშიც თანდათანობით შევიყვანთ მონაცემებს
მომხმარებლებზე და ქალაქებზე, რომლებშიც ისინი იმყოფებოდნენ.
ციკლში for განვაცხადოთ ორი ცვლადი
user_name და city_name, რომლებშიც
შეინახება მომხმარებლის სახელი და ქალაქის დასახელება.
შემდეგ დავწეროთ პირობა - თუ
მომხმარებელი არ არის user_cities_dct-ში, მაშინ ის
დაემატება ამ ლექსიკონს გასაღების სახით.
ასევე მივუთითოთ პირობა, რომ თუ city_name
არ არის None, მაშინ ის დაემატება როგორც გასაღების
მნიშვნელობა:
result = cursor.fetchall()
user_cities_dct = {}
for row in result:
user_name = row['user_name']
city_name = row['city_name']
if user_name not in user_cities_dct:
user_cities_dct[user_name] = []
if city_name is not None:
user_cities_dct[user_name].append(city_name)
print(user_cities_dct)
პრაქტიკული ამოცანები
დავუშვათ, რომ პროდუქტი შეიძლება ეკუთვნოდეს რამდენიმე კატეგორიას. აღწერეთ შენახვის სტრუქტურა.
დაწერეთ მოთხოვნა, რომელიც მიიღებს პროდუქტებს მათი კატეგორიებით ერთად.
გამოიტანეთ მიღებული მონაცემები ul სიის სახით
ისე, რომ თითოეულ li-ში
თავიდან იყოს პროდუქტის სახელი, ხოლო შემდეგ
ორობითის შემდეგ მძიმით გამოყოფილი იყოს
ამ პროდუქტის კატეგორიები. დაახლოებით ასე:
<ul>
<li>product1: category1, category2, category3</li>
<li>product2: category1, category3</li>
<li>product3: category1</li>
</ul>