Pythonda bog‘lanishlar jadvali orqali bog‘lanish

Endi foydalanuvchi turli shaharlarda bo‘lgan deylik. Bu holatda foydalanuvchilar jadvali quyidagicha ko‘rinishi mumkin:

users
id name city
1 user1 city1, city2, city3
2 user2 city1, city2
3 user3 city2, city3
4 user4 city1

Ma'lumki, ma'lumotlarni shu tarzda saqlash noto‘g‘ri - shaharlarni alohida jadvalga chiqarish kerak. Mana u:

cities
id name
1 city1
2 city2
3 city3

Biroq, biz har bir foydalanuvchi bir nechta shaharga murojaat qilishi mumkin bo‘lishini ta'minlashimiz kerak. Buni ikkita jadval yordamida qilish mumkin emas.

Bizga bog‘lanishlar jadvali deb ataladigan narsani kiritish kerak bo‘ladi, u foydalanuvchini uning shaharlari bilan bog‘lab turadi.

Ushbu jadvalning har bir yozuvida foydalanuvchi va uning bir shahari o‘rtasidagi bog‘lanish saqlanadi. Bunda bitta foydalanuvchi uchun bu jadvalda u nechta shaharda bo‘lsa, shuncha yozuv bo‘ladi.

Mana bizning bog‘lanishlar jadvalimiz:

users_cities
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

Foydalanuvchilar jadvali faqat foydalanuvchilarning ismlarini, bog‘lanishlarsiz saqlaydi:

users
id name
1 user1
2 user2
3 user3
4 user4
5 user5

So‘rovlar

Keling, foydalanuvchilarni ularning shaharlari bilan birga olib keladigan so‘rov yarataylik. Buning uchun bizga ikkita join kerak bo‘ladi: birinchi join foydalanuvchilarga bog‘lanishlar jadvalini qo‘shadi, ikkinchi join esa bog‘lanishlar orqali shaharlarni qo‘shadi:

sqlSELECT
  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

So‘rov natijasi

Pythonda bizning so‘rovimiz natijasi har bir foydalanuvchi nomini, u nechta shahar bilan bog‘langan bo‘lsa, shuncha marta o‘z ichiga oladi:

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}

Bunday lug‘atni konvertatsiya qilib, uni quyidagicha aylantirish qulayroq bo‘lardi:

python{
  'user1': ['city1', 'city2', 'city3'],
  'user2': ['city1', 'city2'],
  'user3': ['city2', 'city3'],
  'user4': ['city1'],
  'user5': []
}

Bunday konvertatsiyani bajaradigan kod yozamiz. Bo‘sh user_cities_dct lug‘atini yaratamiz, unga foydalanuvchlar va ular bo‘lgan shaharlar haqida ma'lumotlarni bosqichma-bosqich kiritamiz. for tsikilda user_name va city_name deb nomlangan ikkita o‘zgaruvchi e'lon qilamiz, ular foydalanuvchi nomi va shahar nomini saqlaydi. Keyin shartni belgilaymiz - agar foydalanuvchi user_cities_dct da bo‘lmasa, u ushbu lug‘atga kalit sifatida qo‘shiladi. Shuningdek, agar city_name None bo‘lmasa, u kalit qiymati sifatida qo‘shilishini ko‘rsatamiz:

pythonresult = 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)

Amaliy vazifalar

Задание 1

Mahsulot bir nechta turkumlarga tegishli bo‘lishi mumkin deylik. Saqlash tuzilmasini tasvirlab bering.

Задание 2

Mahsulotlarni ularning turkumlari bilan birga olib keladigan so‘rov yozing.

Задание 3

Olingan ma'lumotlarni ul ro‘yxati ko‘rinishida chiqaring, har bir li da avval mahsulot nomi, keyin ikki nuqtadan keyin vergul bilan ajratilgan holda ushbu mahsulotning turkumlari sanab o‘tilgan bo‘lsin. Taxminan shunday:

html<ul>
  <li>product1: category1, category2, category3</li>
  <li>product2: category1, category3</li>
  <li>product3: category1</li>
</ul>