Autor | Zpráva | ||
---|---|---|---|
petr Profil * |
#1 · Zasláno: 12. 12. 2015, 12:58:27
Dobrý den,
mám tuto strukturu a data v tabulkách: CREATE TABLE IF NOT EXISTS `article` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `t2_in` varchar(200) CHARACTER SET latin1 NOT NULL, `title` varchar(200) DEFAULT NULL, `text` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ; INSERT INTO `article` (`id`, `t2_in`, `title`, `text`) VALUES (1, '1,2,3', 'titulek 1', 'text1...'), (2, '1,4', 'titulek 2', ' text2...'); CREATE TABLE IF NOT EXISTS `tag` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(800) CHARACTER SET utf8 COLLATE utf8_czech_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; INSERT INTO `tag` (`id`, `name`) VALUES (1, 'první'), (2, 'druhý'), (3, 'třetí'), (4, 'čtvrtý'); Ponechme prosím stranou, že ta struktura je špatně v tom, že sloupec t2_in měl být správně jako vazebná tabulka.
Zajímá mě, proč dotaz: SELECT *, (SELECT GROUP_CONCAT(tag.name) FROM tag WHERE id IN (article.t2_in) ) FROM article t2_in vyjmenované?
|
||
Alphard Profil |
#2 · Zasláno: 12. 12. 2015, 13:15:02
Já být návrhář db enginu, vrátím vám nekompromisně null... Vy hledáte číslo ve stringu, tohle
'1,2,3' je řetězec, ne seznam. Mysql si to konvertuje na číslo 1 (přečte co může a zbytek zahodí). Když změníte pořadí těch id, bude výsledek odpovídat prvnímu číslu, např. pro '3,2,1' to vrátí 'třetí' .
|
||
petr Profil * |
#3 · Zasláno: 12. 12. 2015, 14:18:53
Alphard:
Jenže když si tam manuálně dosadím ty idečka třeba takto: SELECT *, (SELECT GROUP_CONCAT(tag.name) FROM tag WHERE id IN (1,2,3) ) FROM article |
||
lionel messi Profil |
petr:
Lenže je rozdiel medzi: 1, 2, 3 (výpočet čísel)
a '1, 2, 3' (string)
|
||
petr Profil * |
#5 · Zasláno: 12. 12. 2015, 14:30:57
lionel messi:
Hm, už to začínám chápat. Převod ze stringu na čísla (něco na způsob split string) MySQL záměrně neobsahuje. Takže když si to tam dosadím přes PHP, tak mi to projde a zázrakem se z toho stane "seznam čísel", zatímco když si to tam dosadím přímo v dotazu, tak mám smůlu. |
||
lionel messi Profil |
#6 · Zasláno: 12. 12. 2015, 14:37:10
petr:
Celý problém vyplýva z toho, že „ta struktura je špatně v tom, že sloupec t2_in měl být správně jako vazebná tabulka“.
|
||
petr Profil * |
#7 · Zasláno: 12. 12. 2015, 14:47:14
lionel messi:
Ale to je přeci jedno. Kterou normální formu se rozhodnu dodržovat je snad moje věc. Ten dotaz není z principu špatně, jen to prostě MySQL záměrně sabotuje. |
||
lionel messi Profil |
#8 · Zasláno: 12. 12. 2015, 14:50:43
petr:
„Kterou normální formu se rozhodnu dodržovat je snad moje věc.“ Treba však počítať s tým, že niektoré zlé návrhy môžu spôsobovať problémy. |
||
Alphard Profil |
#9 · Zasláno: 12. 12. 2015, 16:23:57
petr:
„Ten dotaz není z principu špatně, jen to prostě MySQL záměrně sabotuje.“ Ale kdepak, svět se proti vám nespiknul, jen nechápete všechny souvislosti. Kdyby se dotaz skutečně vykonal tak, jak vy chcete, docházelo by k vyhodnocení uložených dat jako dotazu, v podstatě ekvivalentu eval. Což by byla (kromě jiného) obrovská bezpečnostní díra. |
||
petr Profil * |
#10 · Zasláno: 12. 12. 2015, 19:05:30
Alphard:
Tak evidentně to MySQL alespoň částečně vyhodnocuje, když je schopné z toho vyseparovat to první číslo, viz [#2] . V IN mají být prostě nějaké hodnoty oddělené čárkami, na tom přece není co vyhodnocovat. Když použiju SELECT *, (SELECT GROUP_CONCAT(tag.name) FROM tag WHERE id = 1 OR id = 2 OR id = 3 ) SELECT *, (SELECT GROUP_CONCAT(tag.name) FROM tag WHERE id = nejaky_jiny_sloupec ) |
||
juriad Profil |
#11 · Zasláno: 12. 12. 2015, 19:26:04
IN chce čárkami oddělený seznam prvků. Tento seznam může obsahovat i jen jedný prvek. Každý prvek musí být stejného datového typu jako je sloupec, se kterým se porovnává. Není-li, použijí se běžná pravidla pro přetypování. Pro číselný sloupec a řetězec to znamená, že se pokusí z řetězce udělat číslo - hladově - vezme nejdelší začátek řetězce, který lze chápat jako číslo a zbytek zahodí. Toto přetypování se provádí dlouho poté, co se identifikují jednotlivé prvky seznamu.
|
||
Časová prodleva: 8 let
|
0