История на поръчките

teroristd

Registered
Здравейте, как се прави история на поръчките? Имам таблица orders в която е цялата информация за поръчката. Сложил съм уникален индетификатор, вместо дата за да различавам, поръчките на един и същи клиент, но не мога да си формулирам какви заявки да правя за да се получи.

Ето примерно какво имам в таблицата. Ид 1 и 2 са една поръчка, а ид 3 друга.

orders

id | email | name | price | unic_id
----------------------------------------
1 | asd@ | Ivan | 10 | 111111

2 | asd@ | Ivan | 50 | 111111

3 | asd@ | Ivan | 20 | 222222
 
Аз не мога да разбера какво точно питаш. Имам предвид, иформацията, която си дал е малко оскъдна и неразбираема.
За мен и трите са различни, ако съдим, че ID 1 е цена 10, а ID 2 е цена 50.
Ако може малко по-подробно да обясниш какво точно искаш да се получи, има ли свързани таблици и т.н.
 
teroristd каза:
Здравейте, как се прави история на поръчките? Имам таблица orders в която е цялата информация за поръчката. Сложил съм уникален индетификатор, вместо дата за да различавам, поръчките на един и същи клиент, но не мога да си формулирам какви заявки да правя за да се получи.

Ето примерно какво имам в таблицата. Ид 1 и 2 са една поръчка, а ид 3 друга.

orders

id | email | name | price | unic_id
----------------------------------------
1 | asd@ | Ivan | 10 | 111111

2 | asd@ | Ivan | 50 | 111111

3 | asd@ | Ivan | 20 | 222222

Ако правиш история на поръчките на определен потребител, то unic_id трябва да ти е равно на id-то на потребителя. Така ще обвържеш поръчката с потребителя от който е и ще направиш един селект от сесията:

[sql]
SELECT * FROM orders WHERE unic_id=$userId
[/sql]

А ако просто искаш да изведеш там където се съдържат еднакви стойности:

[sql]
SELECT unic_id
FROM orders
GROUP BY unic_id
HAVING count(*) > 1
[/sql]
 
Искам да направя история на поръчките.

В смисъл да извеждам информацията за старите поръчки в профила на потребителя.

Нямам други свързани таблици.

В тази примерна таблица която съм дал, е все едно някакъв потребител има две поръчки. Поръчка едно съдържа примерно два предмета. Те отговарят съответно на id1 и id2 и имат едно и също unic_id. Третият запис е втора поръчка от един предмет с друго unic_id.

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

В смисъл да извеждам информацията за старите поръчки в профила на потребителя.

Нямам други свързани таблици.

В тази примерна таблица която съм дал, е все едно някакъв потребител има две поръчки. Поръчка едно съдържа примерно два предмета. Те отговарят съответно на id1 и id2 и имат едно и също unic_id. Третият запис е втора поръчка от един предмет с друго unic_id.

Трябват ли ми други таблици? Изобщо как се прави подобно нещо?

Дай по-конкретен пример, защото ме объркваш малко и не схващам, какво точно си навързал. Трябва да навържеш потребителя с поръцката тоест в една от колоните да запаметяваш идентификатора на потребителя направил поръчката, за да знаеш от кой точно потребител е направена тя. Щом имаш това просто вадиш където идентификатора на потребителя съвпада в таблицата с поръчките.
 
dakata__92 каза:
teroristd каза:
Здравейте, как се прави история на поръчките? Имам таблица orders в която е цялата информация за поръчката. Сложил съм уникален индетификатор, вместо дата за да различавам, поръчките на един и същи клиент, но не мога да си формулирам какви заявки да правя за да се получи.

Ето примерно какво имам в таблицата. Ид 1 и 2 са една поръчка, а ид 3 друга.

orders

id | email | name | price | unic_id
----------------------------------------
1 | asd@ | Ivan | 10 | 111111

2 | asd@ | Ivan | 50 | 111111

3 | asd@ | Ivan | 20 | 222222

Ако правиш история на поръчките на определен потребител, то unic_id трябва да ти е равно на id-то на потребителя. Така ще обвържеш поръчката с потребителя от който е и ще направиш един селект от сесията:

[sql]
SELECT * FROM orders WHERE unic_id=$userId
[/sql]

А ако просто искаш да изведеш там където се съдържат еднакви стойности:

[sql]
SELECT unic_id
FROM orders
GROUP BY unic_id
HAVING count(*) > 1
[/sql]

Поръчката си ми е обвързана с потребителя чрез имейла. Ако е само една аз нямам проблеми да изведа всеки един продукт от нея. Проблема е като има повече от една поръчка във времето. За това съм сложил това unic_id, за да разграничавам поръчките на един и същи потребител.

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

Примерно:

items - id, name, description, quantity, price per unit (може и други данни, но в момента описвам накратко)

orders - id, user_id, item_id, quantity, date_added

users - id, .... (тука си наясно)

И от там вече можеш да си JOIN-ваш, за да извличаш информацията.

[sql]
SELECT *
FROM orders
LEFT JOIN items ON orders.item_id = items.id
LEFT JOIN users ON orders.user_id = users.id
WHERE orders.user_id = @userId
[/sql]

По този начин просто взимаш quantity за количество, освен ако не искаш да ти се извеждат като две отделни поръчки.
 
Revelation каза:
По този начин просто взимаш quantity за количество, освен ако не искаш да ти се извеждат като две отделни поръчки.

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

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

Както казах във всяка поръчка се записва и имейла на потребителя, и ако искам всички поръчки просто казвам select * from orders where email = $email, проблема е как да ги изведа разделени една от друга?
 
Е като извикаш всички записи за конкретния потребител, ще си ги имаш разделени.
Ако искаш да групираш тези с еднакви unic_id просто използвай GROUP BY unic_id клаузата.
 
Той май иска друго - иска да раздели поръчките, примерно в поръчка 1 потребителят е поръчал items с id 1,2,3 , а в поръчка 2 - items 5,6,7

Тогава в таблица orders primary key ти е (order_id, item_id) и при финализацията на поръчката може да добавяш order_id в таблица order_history(order_id,user_id,....) с primary key (order_id,user_id)
 
Според мен трябва да дадеш пълната структура на базата, за да можем да помогнем по-адекватно.
Една примерна структура, която ще ти позволи да правиш подобни заявки:

users - id | name | email | ...
products - id | name | ...
orders - id | user_id | date | ...
orders-products - id | order_id | product_id | price | quantity | ...

По този начин всяка поръчка ще ти е свързана с определен потребител, за всяка поръчка ще имаш информация за продуктите в нея, както и цената им в момента на поръчката. Последното е изключително важно и често се пренебрегва, но в дългосрочен план цените се променят, затова е наложително (за нуждите на отчетността) да съхраняваш моментната цена. С правилната структура живота става песен:

[sql]--Всички поръчки на даден потребител
SELECT * FROM orders WHERE user_id = ?

--Поръчки на даден потребител, брой продукти и сума
SELECT op.order_id, count(op.product_id) as broi_produkti, sum(op.price * op.quantity) as suma
FROM orders o
JOIN orders-products op ON o.id = op.order_id
WHERE o.user_id = ?
GROUP BY op.order_id

--Най-поръчвани продукти от даден потребител
SELECT products.*, sum(op.quantity)
FROM orders o
JOIN orders-products op ON o.id = op.order_id
JOIN products ON op.product_id = products.id
WHERE o.user_id = ?
GROUP BY op.product_id
ORDER BY 2 DESC
--Или за най-поръчвани продукти изобщо - без WHERE клаузата

--И т.н., ако ти трябва нещо конкретно и не можеш да си направиш заявката ще помогна[/sql]
 
Ще дам пълната структура на базата щом е необходимо, но нека преди това да се опитам да обясня отново какво точно искам, и какво се случва всъщност.

За да държим нещата прости нека да си представим че има само един потребител който се казва Иван. Той има две поръчки. Първата е била преди една седмица(14.08.17г.) и съдържа два продукта(дрехи), да кажем един чифт дънки и една блуза. Поръчката е изпълнена и продуктите са записани в таблицата orders.

PHP:
 id   | name |    email    | product | size | order_id |  price | ...
 ----------------------------------------------------------------------
 1    | Иван | ivan@abv.bg |  дънки  |   М  |    1     |  30лв. | ...
 2    | Иван | ivan@abv.bg |  блуза  |   L  |    1     |  10лв. | ...

В тази поръчка всичко е било наред, сметнал съм общата цена(40лв.), показал съм правилните снимки и т.н.

Да кажем днес(21.08.17г.) Иван прави нова поръчка. Тя съдържа един продукт, например яке. Продуктът ще се запише в таблицата orders с id - 3.

PHP:
 id   | name |    email    | product | size | order_id |  price | ...
 ----------------------------------------------------------------------
 1    | Иван | ivan@abv.bg |  дънки  |   М  |    1     |  30лв. | ...
 2    | Иван | ivan@abv.bg |  блуза  |   L  |    1     |  10лв. | ...
 3    | Иван | ivan@abv.bg |   яке   |   L  |    2     |  50лв. | ...

Тук вече идва проблема. Аз искам да изведа и двете поръчки, но разделени една от друга. Лесно мога да селектирам всичко но то ще изглежда като една поръчка. Няма да се знае че преди една седмица е поръчал два продукта а сега само един. Няма да може да се сметне общата цена, на всяка отделна поръчка и т.н. Затова добавих поле order_id, за да различавам поръчките, но пак не се сещам как хем да са двете, хем да са разграничени една от друга.

Искам това което ще вижда потребителя да е нещо подобно.

PHP:
Поръчка 1
 -------------------------------------------------------------------
 1 |снимка на продукта | размер | количество | цена |
 2 |снимка на продукта | размер | количество | цена |
 | обща цена |

Поръчка 2
 -------------------------------------------------------------------
 1 |снимка на продукта | размер | количество | цена |
 | обща цена |
 
Много офф много нещо ...
както и да е,
@teroristdмисля че в случая че ти трябва фукция като group_concat за продукти цени и прочие, селектваш по email и групираш по order_id

Код:
SELECT GROUP_CONCAT(product) as order_product, GROUP_CONCAT(price) as order_price FROM orders WHERE email="neshoto@si.bg" GROUP BY order_id

Това е спрямо таблицата която си дал. Ако имаш поле за дата може да ги сортираш по нея
 
Принципно структурата ти не е добра, ама въобще. Но така си избрал, твое решение.
Заявката, която даде @mapka7a ще работи за твоя случай, само трябва да си я обработиш при извикване.
 
Превръщаш данни в стринг след това го сплитваш отново към данните от които си го съставил.
 
ttta каза:
Превръщаш данни в стринг след това го сплитваш отново към данните от които си го съставил.

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

PHP:
$sth = $dbh->query("SELECT * FROM orders WHERE email='ivan@abv.bg' ORDER BY order_id");
$result = $sth->fetchAll(PDO::FETCH_ASSOC);

echo "<pre>";
$i = 1;
$lastId = 0;
foreach ( $result as $row ) {
	if ($row['order_id'] > $lastId ) {
		echo "Поръчка #" . $i . PHP_EOL;
		$lastId = $row['order_id'];
		$i++;
	}
	echo "\t Предмет: " . $row['product'] . PHP_EOL;
}
echo "</pre>";

Резултат:
PHP:
Поръчка #1
	 Предмет: дънки
	 Предмет: блуза
Поръчка #2
	 Предмет: яке
 
Решението е спрямо това което е дал, като структура
Ако иска да преправи решението/структура, нека пусне нова тема за кодревю и ше му се даде по-адекватно решение ....
Съжелявам за оффтопика
 
Значи искаш да направиш история на поръчки :).
Гледам искаш да изкараш:Име на човека,име на продукта,опция на продукта(цвят или размер),цена.


Това са няколко заявки не е само една.
Първо да е всичко читаво трябва да имаш таблица за потребител където при заявка да се вписва това ще е само при регистрирани потребители няма как да стане при гости нали знаеш.
Представи си че след време искаш да излизат в админ панел тези неща и да филтрираш и тем-подобни :D.


Ето ти един пример как аз направих но това е за сериозен проект и е MVC.

Таблици:
order
order_product
order_option
order_status
order_total


order - държа имената на клиента,email,телефон,адрес,инфо за фактура.

order_product
- име,цена,модел...

order_option- тука държа какво е избрал като цвят и опция и цената на опцията и още неща за опцията която е избрал даден клиент.

Малко става сложно но ако искаш за напред всичко да е окей и да нямаш проблеми така се прави, пробвал съм по твоят начин и после става лошо.

После заявките са ти така.

Вземи продукт:

$query("SELECT * FROM order_product WHERE order_id = '" . (int)$order_id . "' AND order_product_id = '" . (int)$order_product_id . "'");

Вземи опции:
$query("SELECT * FROM order_option WHERE order_id = '" . (int)$order_id . "' AND order_product_id = '" . (int)$order_product_id . "'");


А ако вече имаш таблица и искаш директно от поръчките да изкараш, правиш по User ID търсиш поръчката и по числа, ама след време ще си имаш големи проблеми, php не е много бързо.
 
@teroristd, мисля че наистина трябва да обмислиш промяна на структурата. Тази таблица противоречи на основни правила в релационните БД.
Относно резултата, който се опитваш да постигнеш - общата практика е да се използват 2 заявки - 1 за поръчките и 1 за продуктите. За да постигнем по-добра производителност на работа правим магии с JSON, но използваме PostgreSQL. Направил съм ти пример с MySQL (v8.0), нямам наблюдения над производителността на JSON функциите там, но целта е да добиеш представа как става с 1 заявка и сам да се убедиш, че имаш нужда от по-добра структура на данните:
https://www.db-fiddle.com/f/35bEH7zoCenrs8ZKtXM3YQ/1

В php можеш да направиш json_decode на колоната с продуктите и да получиш масив от обекти, като всеки обект ти е продукт в поръчката. Ако ти трябва помощ съм насреща.
А ето и няколко въпроса на които отговорите трябва да те наведат на мисълта за промяна структурата:
Как ще направиш групиране по продукти?
Как ще записваш и извеждаш по няколко поръчани бройки от 1 и същ продукт?
Как ще реализираш функция "повтори поръчката"? А при променена цена? А с проверка за наличност?
От къде ще дойде информацията за тези продукти? Вероятно имаш таблица с продукти - използвай я.

ПС: Мисля, че ще ти е много полезно да прочетеш нещо кратко (5-10мин) с примери за нормализация на БД (1,2,3-то ниво) и да се опиташ да си нормализираш таблицата.
След това можеш да разгледаш базата данни Northwind (google it) и да почерпиш вдъхновение :D
 
Безсмислени гимнастики. Дори при разделяне на структурата си му е нужна 1 заявка. Логиката не е трудно да се направи с PHP.

@raiden, примера ти е добър, но не съм сигурен колко хостинг компании поддържат 8 версия на MySQL.
 

Горе