Tomasz Kiełbowski

Tomasz Kiełbowski Dyrektor ds.
Klientów Kluczowych,
Vernity

Temat: DISTINCT i zestawienie dane z dwóch tabel w mysql

Mam 2 tabele o identycznej strukturze:
historia_prywatne
historia_firmy

Zapisuje w niej wypożyczenia sprzętu. Potrzebuje wyjąć z obu tabel, bez powtórzeń, numery wypożyczanego sprzętu.
Jedyne co mi przychodzi do głowy to tymczasowo spiąć obie tabele w jedną tymczasową i następnie użyć DISTINCT.
np:
$z_lista_unikalnych = mysql_query ("SELECT DISTINCT nr_sprzetu FROM tmp_historia");

Zastanawiam się czy utworzenie tymczasowej tabelki, następnie zastosowanie zapytani z DISTINCT i później skasowanie tymczasowej tabeli, nie będzie się "czkało" przy kilku tysiącach wpisów. Z tego powodu zacząłem się zastanawiać nad zapytaniem bez tworzenia tymczasowej tabeli. Niestety przy moim poziomie wiedzy, nie potrafię tego napisać.
Czy ktoś pomoże złapać trop?
Marcin Mackiewicz

Marcin Mackiewicz Programista JAVA, RS
Adware Polska

Temat: DISTINCT i zestawienie dane z dwóch tabel w mysql

Masz dwa sposoby.
1. Tworzysz sobie widok:
CREATE VIEW historia AS 
SELECT * FROM historia_prywatne
UNION ALL
SELECT * FROM historia_firmy;
i potem wyciągasz dane
SELECT DISTINCT nr_sprzetu FROM historia;


2. Wyciągasz dane jednym zapytaniem SQL bez widoku
SELECT DISTINCT nr_sprzetu FROM (
SELECT * FROM historia_prywatne
UNION ALL
SELECT * FROM historia_firmy
) AS ret;

Skoro to takie same tabele o identycznej strukturze to wypadałoby dane przenieść do jednej tabeli z dodatkową kolumną id_typu_historii która prowadziłaby do słownika i np. id = 1 to prywatne a id_2 to firmowe.

Albo jeszcze wyżej przy kontrahencie/kontakcie info czy prywatny czy firma i na podstawie kontaktu który wypożyczał decydować czy prywatne czy firmowe. Wypożyczenia dotyczą sprzętu więc historia wypożyczeń dotyczy sprzętu i zawiera info o wypożyczającym. Historia nie powinna być trzymana w dwóch oddzielnych tabelach :)

Piszę trochę lakonicznie ponieważ miałem dzisiaj ciężki dzień...

Jeżeli numer sprzętu nie jest kluczem głównym proponuję założyć index na kolumnie.
Przyśpieszy to działanie przy ogromnej ilości wierszy.Ten post został edytowany przez Autora dnia 16.10.14 o godzinie 21:20
Tomasz Kiełbowski

Tomasz Kiełbowski Dyrektor ds.
Klientów Kluczowych,
Vernity

Temat: DISTINCT i zestawienie dane z dwóch tabel w mysql

Marcin M.:
Skoro to takie same tabele o identycznej strukturze to wypadałoby dane przenieść do jednej tabeli z dodatkową kolumną id_typu_historii która prowadziłaby do słownika i np. id = 1 to prywatne a id_2 to firmowe.

Myślałem o id 1=prywatne, 2 firmowe, ale obawiałem się czy przypadkiem za szybko nie będzie mi rosła tabela i nie spowoduje to opóźnień w odczycie. Miesięcznie będzie się pojawiać w historii około 1000 - 1500 wpisów.
Pisałem już wcześniej aplikacje z bazą w mysql, ale tam ilość wpisów w ciągu miesiąca oscyluje na poziomie 100.
Albo jeszcze wyżej przy kontrahencie/kontakcie info czy prywatny czy firma i na podstawie kontaktu który wypożyczał decydować czy prywatne czy firmowe. Wypożyczenia dotyczą sprzętu więc historia wypożyczeń dotyczy sprzętu i zawiera info o wypożyczającym. Historia nie powinna być trzymana w dwóch oddzielnych tabelach :)

Tak by się dało zrobić, ponieważ buduję bazę tylko dla firm. Wypożyczenia prywatne są dodawane "z ręki" i jeśli są uregulowane to po 3 miesiącach mają być kasowane. Każda firma ma swoje id, a prywatnych oznaczam numerem 1. W sumie to chyba nic nie stoi na przeszkodzie, żeby jeszcze sprostować tą historię do jednej tabeli.
Piszę trochę lakonicznie ponieważ miałem dzisiaj ciężki dzień...

Jest ok, wszystko napisałeś w sposób zrozumiały.
Jeżeli numer sprzętu nie jest kluczem głównym proponuję założyć index na kolumnie.
Przyśpieszy to działanie przy ogromnej ilości wierszy.
index ....hmm? nigdy tego nie stosowałem. Poczytam o tym. Mam tylko założony klucz podstawowy, ale na innej kolumnie.

Dzięki
Marcin Mackiewicz

Marcin Mackiewicz Programista JAVA, RS
Adware Polska

Temat: DISTINCT i zestawienie dane z dwóch tabel w mysql

Podejrzewam, że bezpośrednio do całych danych nie będziesz się odnosił na warstwie widoku aplikacji którą posiadasz.
Korzystał będziesz raczej przez wyświetlanie listy wypożyczeń na kontakt lub listy reprezentującej historię wypożyczeń danej sztuki asortymentu przez kontakty. Oznacza to, że przy zapytaniu do takiej tabeli zastosujesz where id_kontaktu = x lub nr_sprzetu = x. Przy 500k rekordów nie powinieneś mieć czasów większych niż 500ms na jedno żądanie z warstwy aplikacji. Wszystko zależy jeszcze od sprzętu na którym stoi baza danych.
Czas dostępu do danych możesz skrócić kilkukrotnie poprzez stosowanie index'u na kolumnie którą stosujesz w klauzuli WHERE. Poczytaj o index'ach to pomaga :)

Temat: DISTINCT i zestawienie dane z dwóch tabel w mysql

select numer from historia_prywatne
union
select numer from historia_firmy
Przemysław Mierkowski

Przemysław Mierkowski Software Developer

Temat: DISTINCT i zestawienie dane z dwóch tabel w mysql

Tomasz K.:
Myślałem o id 1=prywatne, 2 firmowe, ale obawiałem się czy przypadkiem za szybko nie będzie mi rosła tabela i nie spowoduje to opóźnień w odczycie. Miesięcznie będzie się pojawiać w historii około 1000 - 1500 wpisów.
Pisałem już wcześniej aplikacje z bazą w mysql, ale tam ilość wpisów w ciągu miesiąca oscyluje na poziomie 100.

Dla baz danych to są bardzo małe liczby. (1500 * 365 ~ 500 000)
0.5 mln rekordów dla dobrze zaprojektowanej tabeli to jest nic.
Dużo większe obciążenia będzie ci generowało używanie UNION.

Najlepiej, jak stworzysz jedną tabelę ze statusami 1/2 jak pisałeś, tylko koniecznie nadaj indeksy na polach po jakich chcesz szukać.

Ja w pracy mam tabele które mają dziesiątki milionów rekordów i działają bardzo sprawnie.
Tomasz Kiełbowski

Tomasz Kiełbowski Dyrektor ds.
Klientów Kluczowych,
Vernity

Temat: DISTINCT i zestawienie dane z dwóch tabel w mysql

Wasze rady, bardzo mi się przydały. Mam jeszcze jedno małe pytanie (trochę obok tematu, ale nie chciałem zakładać nowego posta).

Chcę utworzyć kolumny do tabeli. Kolumny mają utworzyć się na podstawie wczytanej przez pętlę zmiennej:

$z_lista_unikalnych = mysql_query ("SELECT DISTINCT pojemnosc FROM lista_kontenerow");
//odczytaj pojemnosci kontenerów While ($w_lista_unikalnych = mysql_fetch_array($z_lista_unikalnych))
{
$pojemnosc = $w_lista_unikalnych[0];
$zap = 'ALTER TABLE cennik ADD p'.$pojemnosc.' char(10)';
$sql = mysql_query ($zap); echo'<br />Poj: '.$pojemnosc;
}

Problemy:
1. Nazwy $pojemności są wartościami liczbowymi (2.5 / 2.7 / 3 itd). Żeby kolumna się dodała muszę wstawić prefiks "p" przed nazwą numeryczną. Inaczej kolumna się nie doda.
2. W bazie tworzy się tylko jedna kolumna o nazwie ostatniej przypisanej wartości do zmiennej $pojemnosc.
Żeby się upewnić, że wszystko jest ok, dodałem do pętli $i++ i wyświetliłem jej wartość "echo $i;" otrzymałem 3 wyniki (dokładnie tyle ile miało być). Nie rozumiem dlaczego nie dodają się 3 kolumny.
Marcin Mackiewicz

Marcin Mackiewicz Programista JAVA, RS
Adware Polska

Temat: DISTINCT i zestawienie dane z dwóch tabel w mysql

Sklej instrukcje ALTER i wykonaj jednym poleceniem. Na pewno przejdzie.
$zap = "";
while (...) {
$zap .= "ALTER TABLE cennik ADD `".$pojemnosc."` char(10);\n";
echo'<br />Poj: '.$pojemnosc;
}
$sql = mysql_query ($zap);
Do dziwnych nazw kolumn użyj
`
przyjmie nazwę kolumny, która jest liczbą zmiennoprzecinkową z kropką w separatorze dziesiętnym,
Tomasz Kiełbowski

Tomasz Kiełbowski Dyrektor ds.
Klientów Kluczowych,
Vernity

Temat: DISTINCT i zestawienie dane z dwóch tabel w mysql

Marcin M.:
Sklej instrukcje ALTER i wykonaj jednym poleceniem. Na pewno przejdzie.
$zap = "";
while (...) {
$zap .= "ALTER TABLE cennik ADD `".$pojemnosc."` char(10);\n";
echo'<br />Poj: '.$pojemnosc;
}
$sql = mysql_query ($zap);
Do dziwnych nazw kolumn użyj
`
przyjmie nazwę kolumny, która jest liczbą zmiennoprzecinkową z kropką w separatorze dziesiętnym,

Działa!! Serdeczne dzięki. Muszę tylko doczytać po co to "n" i będę wszystko kumać :)
Marcin Mackiewicz

Marcin Mackiewicz Programista JAVA, RS
Adware Polska

Temat: DISTINCT i zestawienie dane z dwóch tabel w mysql

\n = znak końca linii... Używam np przy instrukcji echo jak chcę sobie treść zapytania wyświetlić w terminalu. Każdy alter od nowej linii łatwiej się czyta...

Tu masz info: http://php.net/manual/en/language.types.string.php#lan...

Następna dyskusja:

MySQL. Dodawanie danych los...




Wyślij zaproszenie do