Mysql подзаявки?

Имам отчетна таблица, която изглежда подобна на тази

reports
inspection_type | inspection_number
berries         | 111 
citrus          | 222
grapes          | 333

inspection_type в моя случай е името на другата таблица, която бих искал да SELECT * от където inspection_number е равно на report_key на тази свързана таблица.

{fruit}
row      | report_key | etc....
value    | 111        | value
value    | 222        | value

Проблемът е, че не знам как да направя заявка за инспекция_тип, за да получа името на таблицата за запитване на стойността. Има ли смисъл от това?

Опитах това тук, но дори аз знам, че е очевидна грешка:

SELECT inpection_type, inspection_number
FROM reports rpt
ON rpt.inspection_number = report_key
(SELECT * FROM inspection_type WHERE status < '2')
WHERE rpt.status < '2'
ORDER BY rpt.inspection_number DESC

Може ли SQL гуру да ми каже най-добрия начин да направя това?


person ehime    schedule 20.02.2012    source източник
comment
Мисля, че сте се натъкнали на причината, поради която тази DB архитектура е лоша идея.   -  person JohnFx    schedule 21.02.2012
comment
Съгласен съм от все сърце.   -  person ehime    schedule 21.02.2012


Отговори (2)


Тъй като не е възможно да имате променлива за име на таблица директно в TSQL, ще трябва да конструирате динамично TSQL.

Имена на таблици с променливи в съхранени процедури

person Mitch Wheat    schedule 20.02.2012
comment
stackoverflow.com/questions/1325044 / - person Mitch Wheat; 21.02.2012
comment
stackoverflow.com/questions/3646412/ - person Mitch Wheat; 21.02.2012
comment
stackoverflow .com/questions/2754423/ - person Mitch Wheat; 21.02.2012
comment
Съгласен съм, че това е ужасна идея. Вместо това ще измисля начин за предаване на името като променлива в JQuery. - person ehime; 21.02.2012
comment
По-добра идея би била да комбинирате таблиците с тип инспекция в една таблица, така че да не се налага да се занимавате с цялата тази глупост. - person JohnFx; 21.02.2012
comment
Съгласен съм, но те имат много различни размери на колоните. Това наистина е първият ми опит в създаването на DB и все още се опитвам да науча какво трябва и не трябва да правя, това изглежда като огромно не ме питате. - person ehime; 21.02.2012
comment
Този отговор е ГАЗЕН начин да го направите, това е по-голямо нещо, отколкото да работите върху нормализирането на вашите таблици, но хей, тъй като можете да използвате таблица за нормализиране, за да съпоставите inspect_type с целочислен идентификатор. - person Simon at My School Portal; 21.02.2012
comment
Не съм коментирал валидността на решението, тъй като винаги, когато съм го правил в миналото, ме критикуваха, че отговарям с истинското решение, а не просто отговарям на въпроса! Така че да, наличието на имена на таблици в таблица като тази е ужасно решение. - person Mitch Wheat; 21.02.2012
comment

Тъй като трябва да знаете само дали имате по-малко от 3 зададени бита, бих предложил това:

// remove two bits
number &= number - 1;
number &= number - 1;
// if number != 0, then there were 3 or more bits set
return number.IsZero;

Разбира се, методът на Rain също работи и не съм сигурен коя стратегия ще бъде по-бърза.

алтернатива:

//remove one bit
number &= number - 1;
// if the number of bits left is 0 or 1, there were < 3 bits set
return number.IsZero || number.IsPowerOfTwo;

Вероятно е по-бързо първо да тествате и да премахнете бита по-късно:

return number.IsZero ||        // zero bits?
    number.IsPowerOfTwo ||     // one bit?
    (number & (number - 1)).IsPowerOfTwo;  // two bits?
- person ehime; 21.02.2012

Не можете наистина да направите това, към което се стремите, само в SQL, ще трябва или да се забърквате на друг език, или (и това е предпочитаното решение) да преструктурирате базата данни, т.е. (съжалявам за мета-кода)

// Comes in where your existing `reports` table is
inspections (
    inspection_id INT UNSIGNED NOT NULL AI,
    inspection_type_id INT UNSIGNED NOT NULL (links to inspection_types.inspection_type_id)
    .... other rows ....
)

// New table to normalise the inspection types
inspection_types (
    inspection_type_id INT UNSIGNED NOT NULL AI,
    type_name VARCHAR NOT NULL
    .... other rows ....
)

// Normalised table to replace each {fruit} table
inspection_data (
    inspection_data_id INT UNSIGNED NOT NULL AI,
    inspection_id INT UNSIGNED NOT NULL (links to inspections.inspection_id)
    .... other rows ....
)

Тогава вашето запитване ще бъде просто

SELECT * 
FROM inspections

INNER JOIN inspection_types
ON inspection_types.inspection_type_id = inspections.inspection_type_id

INNER JOIN inspection_data
ON inspection_data.inspection_id = inspections.inspection_id

Краткият преглед по-горе е доста неясен, тъй като вашите съществуващи таблични данни не са наистина посочени, но общият принцип е здрав. Дори няма да отнеме много, за да мигрирате данни от съществуващата ви структура, но когато приключите, ще ви даде много по-чисти заявки и ще ви позволи действително да извличате по-лесно данните, които търсите

person Simon at My School Portal    schedule 21.02.2012