Логика в SQL заявка.

13 отговора 776 прегледа
#1

Логика в SQL заявка.

Имам следния проблем. Трябва да правя търсачка за недвижими имоти, където се търсят имоти в определн интервал за цената. Проблема е, че имотите се въвеждат в различни валути и трябва да се съобразявам с актуалните курсове. В базата съм създал едно поле за цената и едно поле за валутата.
Значи, първо правя заявка за всички имоти, които отговарят на зададения интервал за цената, без да правя никакво конвертиране, като освен цената взимам и стойността в полете за валутата (така извличам и имоти, които може и да не отговарят на ценовия диапазон, предвид, че не правя проверка за валутата). След това за всеки имот правя проверка (с PHP), ако валутата му е различна от тази, в която потребителя е събмитнал търсенето, правя конвертиране с курса и след това правя проверка дали новата сума е в търсения (от потребителя) интервал. Ако не е, изключвам офертата от резултата, след това показвам висчки, които са останали.
Тъй като нямам много опит, това е единствената схема, за която се сетих. Нещо ми се вижда много баламска обаче. Ако някой може да предложи по-добра логика, ще съм му много благодарен.

Отговор
в отговор на NecroLamer #2

Re: Логика в SQL заявка.

Защо всички цени да не са ти в една валута.
при пост конверираш данните в тази валута и след това си правиш заявката
SELECT * FROM tbl WHERE price BEETWEN $min AND $max

Break The UnBreakable
Отговор
в отговор на nupaT #3

Re: Логика в SQL заявка.

Продавачите на въпросните недвижими имоти едва ли ще са съгласни да обявават цени само в USD например. По скоро аз бих си избрала една валута : например евро и 1) смятам търсените суми от и до в евро и 2)търся във временна таблица от вида : имот, сметната цена в евро.

Отговор
в отговор на NecroLamer #4

Re: Логика в SQL заявка.

zna4i qvno naistina si novak v taq oblast, nqma stra6no vseki e po4nal ot nqkude.
vzemi popro4eti malko za ERM's (Entity Relationship Models) i kak se pravi Normalization na bazi danni. kakto i da, eto kakvo trqbva da napravi6 spored men, ako sum razbral dobre vuprosut ti:

1. pravi6 o6te edna tablica da kajem Currency kudeto 6te ima 2 koloni naprimer PKEY_Currency (tva e za id-to) i Currency_name (EUR, USD, BGN) i t.n.
2. vmesto kolona Valuta v tablicata Imoti ili neznam kak si q krustil, slaga6 kolona ot sorta FKEY_Currency (tva 6e e foreign key kum tablica Currency). Ei na tva mu se vika Normalization ot 3 nivo, ama kato popre4ete6 malko pove4e 6e se nau4i6.
3. da ne zabravi6 kato slaga6 foreign key da set-ne6 Constraint za ON CASCADE DELETE (neznam s kva database system raboti6 no vajen e principa)

i zaqvkata stava slednata:

SELECT * from Imoti, Currency
WHERE price <uslovieto za cenata> AND FKEY_Currency = PKEY_Currency AND Currency_name=<EUR naprimer>

dano sum razbral pravilno vuprosa i sum pomognal
jiv i zdrav!

Отговор
в отговор на AvB #5

Re: Логика в SQL заявка.

Човекът иска преобразуване на валути, т.е. ако имотът е в долари, а потребителят търси в евро, да се направи преобразуването и да се покажат и имотите в долари. С твоята заявка, ще се покажат само имотите с валутата, в която се търси. А и не виждам причина за това ON CASCADE DELETE или по-точно ОN DELETE CASCADE - далеч по-разумно ми се струва да се остави поведението по подразбиране, а именно - NO ACTION.

Everything louder than everything else...

Редактирано от Dakota на

Отговор
в отговор на _danitu #6

Re: Логика в SQL заявка.

Точно...желателно е само да се пази и оригиналната цена и валута някъде.

Everything louder than everything else...
Отговор
в отговор на Dakota #7

Re: Логика в SQL заявка.

Prav si,
priburzano nedoglejdane ot moq strana i nai-ve4e nedomislen otgovor! za napred 6e vnimavam, obe6tavam!

eto kakvo probvah toku 6to i zasega vurvi pu6ka, makar 4e nqkak si mi se struva mnogo nedalnovidno s tova prevru6tane na valuta ot edna v druga. tuk ve4e trqbva da se poglednat i strani4ni iziskvaniq, kato krustosan kurs ili minavane prez lev, postoqnno obnovqvane na kursa i t.n. i t.n.

zna4i,
kum prednoto predlojenie koeto dadoh, kum tablica Currency se dobavqt o6te tolkova koloni kolkoto valuta imame (naprimer: BGN_CUR, USD_CUR, EUR_CUR ot tip Real-plava6ta zapetaq) v tqh vivejdame krustosanite kursove kato za valuta s PKEY=1; name=EUR; EUR_CUR=1.0; BGN_CUR=1.95; USD_CUR=1.2 kato tova sa da predpolojim teku6tite kursove za denq

togava zaqvkata stava mnoooogo prosti4ka:

SELECT *
FROM Imoti, Currency
WHERE fkey=pkey AND price*<kolonata v kvato valuta se iska> BETWEEN <dolna granica> AND <gorna granica>

ei tva e! ba4ka 100%!

p.s. otdavna ne sum v BG i sum zabravil polovinata BG klavi6i po klaviaturata. zatui 6e izvinqvate za Latinskiq pravopis

Отговор
в отговор на NecroLamer #8

Re: Логика в SQL заявка.

Моето мнение е, че твоето решение не е лошо, а е едно от възможните решения.
Аз се сещам за още две решения:
1. Приемаш си дадена валута за базова. При регистриране на имота пазиш оригиналната валута и цената в оригиналната валута и цената в базовата валута. След това ще търсиш само по стойността на базовата валута. Проблема в този случай е, че при промяна на курсовете ще трябва да преизчисляваш цените на всички засегнати имоти. За мен това решение е подходящо ако курса се дефинира да кажем един път на ден и такова презичисляване няма да е фатално да се прави. Предимството е че заявакта е проста;
2. Пазиш цените на имотите само такак като ги е качил клиента и във валута в която ги е качил. При търсене правиш толкова зявки колкото валути имаш. А можеш да използваш 'OR' и/или вложени заявки. Недостатък е че заявката може да стане сложна особено ако имаш много валути.
Дано да съм помогнал.

Боже колко мъка има на този свят Боже!
Отговор
в отговор на AvB #9

Re: Логика в SQL заявка.

абе пич първо говориш за норамлизация а после казваш да се направи таблица в която да има толкова колони колко валути. а ако трябва да добавим нова валута какво правим?

Боже колко мъка има на този свят Боже!
Отговор
в отговор на NecroLamer #10

Re: Логика в SQL заявка.

Правиш си таблица за валутите с относителната им стойност спрямо избрана от теб валута - например евро:

mysql> SELECT * FROM currency;

+--------------+------+----------+
| currency_sid | name | value |
+--------------+------+----------+
| 1 | EUR | 1 |
| 2 | USD | 0.813337 |
| 3 | CHF | 0.646307 |
+--------------+------+----------+


Имаш и таблицата с имотите, където пазиш оригиналните валути и оригиналните цени:

mysql> SELECT * FROM real_estate;

+-----------------+----------------------+--------+--------------+
| real_estate_sid | name | price | currency_sid |
+-----------------+----------------------+--------+--------------+
| 1 | Къща в Драгалевци | 200000 | 1 |
| 2 | Барака във Факултето | 10000 | 2 |
| 3 | Мезонет в Женева | 300000 | 3 |
+-----------------+----------------------+--------+--------------+


Потребителят въвежда стойности за минимална и максимална стойност на валутите и номер на валутата, съответно: $min_value, $max_value, $currency_sid . Трябват ти всичко на всичко 2 заявки - една за да видиш текущия курс на валутата и втора, за да извадиш самите имоти. Ако не е критично, можеш и още при показване на списъка с валутите да взимаш и текущия курс и при submit директно да рапзолагаш с него - този метод обаче не е сигурен - пак казвам, ако не е критично, така си спестяваш 1 заявка. В противен случай ти трябва това:

SELECT

@curr_value := value
FROM
currency
WHERE
currency_sid=$currency_sid;

SELECT
re.real_estate_sid,
re.name,
re.price AS original_price,
c.name AS original_currency,
re.price * c.value AS price_in_euro
FROM
real_estate re INNER JOIN currency c
ON
re.currency_sid=c.currency_sid
WHERE
re.price * c.value BETWEEN $min_value * @curr_value AND $max_value * @curr_value


Разбира се, вероятно в таблицата с валутите ще имаш и дата, но принципно това не променя нищо - просто ще гледаш курса за текущата дата.

Everything louder than everything else...
Отговор
в отговор на NecroLamer #11

Re: Логика в SQL заявка.

Таблици:

currency (currency_id, name)
currency_rate (date, currency_id, fixing)
estate (estate_id, blaaaaaah,.........., price, currency_id)


Заявка:

select
e.whatever
from
estate e,
currency_rate cr
where
(cr.currency_id = e.currency_id) and
(cr.date = today) and
( (e.price * cr.fixing) between min_shit and max_shit)


What about this shit?

Егати пауъра
Отговор
в отговор на Dakota #12

Re: Логика в SQL заявка.

Извинявам се много за невежеството, но не ми е ясно точно мястото и предназначението на полето 'data'

Отговор
в отговор на timmyyy #13

Re: Логика в SQL заявка.

Про положение, че рейта на валутата ще се пейства от php, нужна ли ми е все още таблицата currency_rate и как би се променила заявката ?

Отговор
в отговор на NecroLamer #14

Re: Логика в SQL заявка.

Представи си, че просто искаш да пазиш курсовете ежедневно за всеки случай. Например ако някой е искал да купи хотел за $1000000 но цената е била в евро и преди един месец си е намерил такъв хотел, но от тогава вече курсът се е променил и ти не искаш да покриваш разходите от около 20-30000 евро...та за този случай, би било добре да можеш да видиш какви съвпадения биха били намерени в базата ти ако датата беше еди-коя си...и т.н.

Everything louder than everything else...
Отговор