Сложна заявка която пресмята и подрежда по процент спад

sentenello

Registered
Здравейте,
Заявката ми представлява това
Код:
SELECT s.name AS sport_name,((c.koef - odd.koef)/c.koef)*100 as `change`,GROUP_CONCAT(odd.koef SEPARATOR '_') AS oddkoef, e.name AS event_name, CONCAT(m.hometeam, ' - ', m.awayteam) AS teams, m.start_date, GROUP_CONCAT(c.name SEPARATOR ' ') AS zalog, GROUP_CONCAT(c.koef SEPARATOR '_') AS koef FROM `event` e LEFT JOIN `sport` s ON e.sportid = s.id LEFT JOIN `match` m ON e.id = m.event_id LEFT JOIN `bettype` b ON m.id = b.match_id LEFT JOIN `choicetype` c ON b.id = c.bet_id LEFT JOIN `oddmove` odd ON c.id = odd.id WHERE odd.koef != '0' AND b.name = 'Match Result' AND m.start_date >= CURDATE() GROUP BY m.id HAVING `koef` > `oddkoef` ORDER BY `change` DESC

И изкарва данни така :D
Код:
sport_name change oddkoef event_name teams start_date zalog koef Football

24.285714 2.65_3.50_2.25 Chilean Apertura Cobresal  -  Universidad Catolica 2014-09-28 21:30:00 1  Draw  2 3.50_3.40_1.88

Всичко до тук е ок. Пресмята дали 3.50 е по-голямо от 2.65 и показва че е по-голямо с 24,28.. Проблема обаче е че се опитвам да проверя не само за първата стойност и заради това ползвам HAVING `koef` > `oddkoef`, но каквото и да опитвам пресмята само първата стойност. Целта е да провери и трите стойности (2.65_3.50_2.25 >3.50_3.40_1.88) и да ги подреди по процент спад.
 
Успях да накарам да пресмята всичко точно с
Код:
HAVING ((`koef` - `oddkoef`)/`koef`)*100 > '1.00'
Но сега не знам какво да задам в ORDER, за да ми ги подрежда от най-голямата към най-малката разлика.

С този код изчислявам колко е процента на спад, и сега искам да ги подредя, по същата тази формула, но все още не мога да разбера как :o

EDIT: Другия проблем е че като задам да има разлика по-голяма от 1.00 и не ми показва тези които са със стойност 6.6667. Пробвах да премахна умножението в HAVING и да го направя > '0.50' примерно, но отново не става. Някакви идеи ?
 
Не мога да ти помогна с тези сложни заявки които правиш, но се чудя няма ли да е по удачно да си правиш всякаквите изчисления с пхп и после просто да си вадиш каквото ти трябва спрямо получения резултат?
 
Отчаях се вече :cry: .Пробвах какви ли не варианти и не се получава.

Ще се опитам да го обясня по-елементарно.

Имам си 2 полета koef и oddkoef които ги групирам по ид и стават така
Код:
koef                           oddkoef
2.65_3.50_2.25           3.50_3.40_1.88

След това с
Код:
HAVING ((`koef` - `oddkoef`)/`koef`)*100 > '1.00'
проверявам едно по едно какви са разликите
(2.65 - 3.50)/2.65)*100 = -32.0754 %
(3.50 - 3.40)/3.50)*100 = 2.8571 %
(2.25 - 1.88)/2.25)*100 = 16.4444 %

В този случай ми извежда срещата, но някой срещи да кажем са с 5.20% и когато задам HAVING ((`koef` - `oddkoef`)/`koef`)*100 > '5.00' не ми ги извежда. Другия ми проблем е, че след като вече съм ги изчислил, не знам как да направя ORDER-a така че да се наредят по проценти спад.
 
Един онлайн тул с който да си форматираш малко заявката :D
http://www.dpriver.com/pp/sqlformat.htm
[sql]SELECT s.name AS sport_name,
( ( c.koef - odd.koef ) / c.koef ) * 100 AS `change`,
Group_concat(odd.koef SEPARATOR '_') AS oddkoef,
e.name AS event_name,
Concat(m.hometeam, ' - ', m.awayteam) AS teams,
m.start_date,
Group_concat(c.name SEPARATOR ' ') AS zalog,
Group_concat(c.koef SEPARATOR '_') AS koef
FROM `event` e
LEFT JOIN `sport` s
ON e.sportid = s.id
LEFT JOIN `match` m
ON e.id = m.event_id
LEFT JOIN `bettype` b
ON m.id = b.match_id
LEFT JOIN `choicetype` c
ON b.id = c.bet_id
LEFT JOIN `oddmove` odd
ON c.id = odd.id
WHERE odd.koef != '0'
AND b.name = 'Match Result'
AND m.start_date >= Curdate()
GROUP BY m.id
HAVING `koef` > `oddkoef`
ORDER BY `change` DESC[/sql]
сега искам да ги подредя, по същата тази формула
Аз не разбрах коя формула?
Тази ли:
Код:
((`koef` - `oddkoef`)/`koef`)*100
Просто добави едно поле
[sql]((`koef` - `oddkoef`)/`koef`)*100 as sort_field
[/sql]и тогава ще сортираш така:
[sql]order by sort_field[/sql]
 
Явно не си ми прочел последния пост, тъй като си писал в това време :D

Трябва да сортират по резултата който излиза от
Код:
HAVING ((`koef` - `oddkoef`)/`koef`)*100
 
Какъв ти е смисъле от такава сложна заявка? Изведи си резултатите и с процедурен код на PHP няма да имаш никакъв проблем с това да ги съхраниш в масив и да си ги визуализираш както пожелаеш. Няма да забавиш кода кой знае колко много с нещо подобно.
 
Единственото което мога да премахна от тази заявка е
Код:
( ( c.koef - odd.koef ) / c.koef ) * 100 AS `change`,
и
Код:
HAVING ((`koef` - `oddkoef`)/`koef`)*100

при което ще вземам всички срещи, без значение дали имат различия между oddkoef и koef. Не съм от най-запознатите, затова направо ще попитам това ли имаш предвид и ако е така, после накъде? :D :oops:

EDIT: Ако не се лъжа, след като всичката информация е вече в масива, сега трябва да я сортирам по дроп-а нали?
 
Ще се опитам да дам направо за какво иде реч, за да може някой така да ми помогне, че да го разбера :D и да се справя.

С тази заявка
[sql]$query = mysql_query ("SELECT s.name AS sport_name,
Group_concat(odd.koef SEPARATOR '_') AS oddkoef,
e.name AS event_name,
Concat(m.hometeam, ' - ', m.awayteam) AS teams,
m.start_date,
Group_concat(c.name SEPARATOR ' ') AS zalog,
Group_concat(c.koef SEPARATOR '_') AS koef
FROM `event` e
LEFT JOIN `sport` s
ON e.sportid = s.id
LEFT JOIN `match` m
ON e.id = m.event_id
LEFT JOIN `bettype` b
ON m.id = b.match_id
LEFT JOIN `choicetype` c
ON b.id = c.bet_id
LEFT JOIN `oddmove` odd
ON c.id = odd.id
WHERE odd.koef != '0'
AND b.name = 'Match Result'
AND m.start_date >= Curdate()
GROUP BY m.id
HAVING ( ( `koef` - `oddkoef` ) / `koef` ) * 100 > '0.50' ");
[/sql]

И този код..
Код:
$events = array();
$rows = array();

while($row = mysql_fetch_assoc($query))

{
    $events[] = $row['event_name'];
    $rows[] = $row;
}
echo"<table>";
// всеки евент ни трябва само веднъж

$events = array_unique($events);
foreach($events as $event)
{
    echo "
	<tr style='color:#FFFFFF;background:url(http://futbolnizalozi.futbolniprognozi.eu/wp-content/themes/PressNow/images/widgettitle-bg.png) left top repeat-x'>
		<td  >$event</td>
		<td> </td>
		<td> Drop: </td>
		<td> 1 </td>
		<td> X </td>
		<td> 2 </td>
	
	</tr>";

    foreach($rows as $key => $val)

    {
	
list($koef_a, $koef_b, $koef_c) = explode('_', $val['koef']);
list($newkoef_a, $newkoef_b, $newkoef_c) = explode('_', $val['oddkoef']);
$chas = date('d.m H:i', strtotime($val['start_date']));
$dropaa = @round(((($koef_a - $newkoef_a) / $koef_a)*100),0);
$dropab = @round(((($koef_b - $newkoef_b) / $koef_b)*100),0);
$dropac = @round(((($koef_c - $newkoef_c) / $koef_c)*100),0);


if (($dropaa > $dropab) AND ($dropaa > $dropac)) {
$biggestdrop = "$dropaa e A ";
$coloraa = 'background-color:red';
$colorab = 'background-color:none';
$colorac = 'background-color:none';
} else
if (($dropab > $dropaa) AND ($dropab > $dropac)) {
$biggestdrop = "$dropab e B";
$colorab = 'background-color:red';
$coloraa = 'background-color:none';
$colorac = 'background-color:none';
}else 
if (($dropac > $dropab) AND ($dropac > $dropaa)) {
$biggestdrop = "$dropac e C ";
$colorac = 'background-color:red';
$colorab = 'background-color:none';
$coloraa = 'background-color:none';
}
        if($val['event_name'] == $event)
        {
            echo"
	<tr class='upcoming';>
		<td>$chas </td>
		<td>$val[teams] </td>
		<td>$val[change] $biggestdrop %</td>
		<td style='font-weight:$boldnato1;$coloraa;'>$newkoef_a $koef_a </td>
		<td style='font-weight:$boldnatox;$colorab;'>$newkoef_b $koef_b </td>
		<td style='font-weight:$boldnato2;$colorac;'>$newkoef_c $koef_c </td>
	</tr>";
            unset($rows[$key]);

        }

    }

}
?>
</table>

Резултата е това

Както виждате процентите са 1,3,13,1,6 и т.н. Това което се чудя е защо примерно когато дам HAVING ( ( `koef` - `oddkoef` ) / `koef` ) * 100 > '1.50' , ми изчезват и някой редове които са с 4%? Няма ли някой код 1 ред, с който да накарам тая таблица да се подреди 30,13,10,6... ?
 
Току що разбрах защо някой ми ги скрива въпреки че са с проценти над 1.50.

Having прави проверка на 3-те стойности, и ако една от тях е под 1,50, заявката пропуска този ред. Някакви идеи как да го преправя на " ако една от стойностите е над 1,50" да взема реда?
 
sentenello каза:
Току що разбрах защо някой ми ги скрива въпреки че са с проценти над 1.50.

Having прави проверка на 3-те стойности, и ако една от тях е под 1,50, заявката пропуска този ред. Някакви идеи как да го преправя на " ако една от стойностите е над 1,50" да взема реда?

Ами изключи го от условието на HAVING-a ?
 
Тъй като съм твърдо решен този код да го донаправя днес, а без помощ няма как да стане, защото изпрочетох де що има, търсих примерни и подобни кодове, но така и не успях.

Сега стигнах до извода че ще си направя заявката така.
Код:
SELECT s.name                                   AS sport_name, 
       ( ( c.koef - odd.koef ) / c.koef ) * 100 AS `change`, 
       odd.koef                                 AS oddkoef, 
       e.name                                   AS event_name, 
       Concat(m.hometeam, ' - ', m.awayteam)    AS teams, 
       m.start_date                             AS start_date, 
       c.name                                   AS zalog, 
       c.koef                                   AS koef 
FROM   `event` e 
       LEFT JOIN `sport` s 
              ON e.sportid = s.id 
       LEFT JOIN `match` m 
              ON e.id = m.event_id 
       LEFT JOIN `bettype` b 
              ON m.id = b.match_id 
       LEFT JOIN `choicetype` c 
              ON b.id = c.bet_id 
       LEFT JOIN `oddmove` odd 
              ON c.id = odd.id 
WHERE  b.name = 'Match Result' 
       AND m.start_date >= Curdate() 
       AND ( ( c.koef - odd.koef ) / c.koef ) * 100 > '5.00' 
ORDER  BY `change` DESC

Което ми изкарва резултатите без да ги групира.
Код:
change
oddkoef
event_name
teams
start_date
zalog
koef

30.434783
8.00
German Bundesliga
Cologne  -  Bayern Munich
2014-09-27 14:30:00
1
11.50

25.000000
7.50
Eng. Premier League
Manchester United  -  West Ham
2014-09-27 15:00:00
2
10.00

23.200000
4.80
Eng. Premier League
Manchester United  -  West Ham
2014-09-27 15:00:00
Draw
6.25

Проблема е че коефициентите не се записват на един ред под формата на кеоф1,коеф2,коефх, а на няколко реда
Код:
мачид   залог              коеф          мач
1           1                       2.00          psv-united
1           2                       3.00          psv-united
1           X                       1.00          psv-united

И кога ги групирам, за да ги изведа на един ред с group_concat, виждате че не мога да го направя да подрежда и да изчислява правилно. Така както показвам малко по-горе, си ги изчислявам правилно и лесно, но не мога да ги групирам и да изведа мача който има change под този вид.

Код:
мачид   залог             коеф                       мач
1           1 Х 2      2,00 1,00 3,00            psv-united
 
Точно по последния ти проблем има тема в stackoverflow:

http://stackoverflow.com/questions/8631210/group-concat-order-by
http://stackoverflow.com/questions/995373/mysql-sort-group-concat-values
Вкарваш order by в group concat -a.
:?:

[sql]... group_concat(`koef` order by `koef` desc SEPARATOR '_' )
[/sql]


[sql]SELECT s.name AS sport_name,
( ( c.koef - odd.koef ) / c.koef ) * 100 AS `change`,
odd.koef AS oddkoef,
e.name AS event_name,
Concat(m.hometeam, ' - ', m.awayteam) AS teams,
m.start_date AS start_date,
c.name AS zalog,
# EDIT START
Group_concat(c.koef order by c.koef desc SEPARATOR '_') AS koef
# EDIT END
FROM `event` e
LEFT JOIN `sport` s
ON e.sportid = s.id
LEFT JOIN `match` m
ON e.id = m.event_id
LEFT JOIN `bettype` b
ON m.id = b.match_id
LEFT JOIN `choicetype` c
ON b.id = c.bet_id
LEFT JOIN `oddmove` odd
ON c.id = odd.id
WHERE b.name = 'Match Result'
AND m.start_date >= Curdate()
AND ( ( c.koef - odd.koef ) / c.koef ) * 100 > '5.00'
# EDIT START
GROUP BY m.id
HAVING `koef` > `oddkoef`
# END EDIT
ORDER BY `change` DESC[/sql]
С коментари съм показал къде съм редактирал последния ти пост :?:

Мисля че чак сега разбрах за какво е ставало дума в цялата тема :D
 
В момента заявката ти работи почти както трябва. (Да спомена че стигнах почти до същото положение по-едно време).

Да обясня само че
Group_concat(c.koef order by c.koef desc SEPARATOR '_') AS koef
събира в koef залозите за 1 Х 2, което означава че koef е
1.60_3.20_6.00... което идва от

Код:
1           X        2
1.60   3.20   6.00

В момента ми подрежда данните правилно(по-голям спад от 5%), и сравнява 3-те стойности поотделно, но когато го изведа вместо да ми изведе

Код:
мач  дроп  1          Х      2
1        3%  2,50  3,20 4,50
То ми извежда
Код:
мач  дроп  1          Х             2
1        3%  2,50  (празно)  (празно)

А целта ми е да извеждам и 3-те коефициента, независимо че само първия има спад.
 
До тук добре, сега ако може някой да ми даде насоки, как да изкарам всичките резултати от полето коеф на този мач, а не само тези които са по-големи от oddkoef , ще съм готов :D
 
Направих си заявката така
[sql]SELECT s.name AS sport_name
,
( ( c.koef - odd.koef ) / c.koef ) * 100 AS
`change`,
e.name AS event_name
,
Concat(m.hometeam, ' - ', m.awayteam) AS
teams,
m.start_date,
Group_concat(c.name SEPARATOR ' ') AS zalog,
Group_concat(c.koef ORDER BY c.koef DESC SEPARATOR '_') AS `koef`,
Group_concat(odd.koef ORDER BY odd.koef DESC SEPARATOR '_') AS `oddkoef`
FROM `event` e
LEFT JOIN `sport` s
ON e.sportid = s.id
LEFT JOIN `match` m
ON e.id = m.event_id
LEFT JOIN `bettype` b
ON m.id = b.match_id
LEFT JOIN `choicetype` c
ON b.id = c.bet_id
LEFT JOIN `oddmove` odd
ON c.id = odd.id
WHERE b.name = 'Match Result'
AND m.start_date >= Curdate()
GROUP BY m.id
HAVING `koef` > `oddkoef`
ORDER BY `change` DESC [/sql]

Всичко си работи перфектно, освен нареждането на самата таблица и това става, защото примерно спада е във втората стойност на коеф-а а то винаги смята първата
Код:
1-ва стойност   2-ра стойност  3-та стойност
1.50                           2.50                3.00
2.00                            2,50               3,00

2.00                           1,50                3,00
2.10                           3,00                3,00

В примера който съм дал ще ми изкара на първо място 1-вото сравнение което съм дал, въпреки че във втората, вторите стойности имат по-голям спад. Когато сложа в WHERE
Код:
AND ( ( c.koef - odd.koef ) / c.koef ) * 100 > '5.00'
Всички се подрежда точно, но ми извежда само стойностите който имат разлика, а не трите
 
За пореден път си ъпвам темата с нова информация от пробите ми :o

Оставих заявката както ми я даде @anonimen, след което във Foreach вкарах нова заявка
Код:
SELECT 
m.id							as mid,
b.name							as zalogime,
cho.koef						as koef,
Concat(m.hometeam, ' - ', m.awayteam)    AS teams,
Group_concat(cho.koef SEPARATOR '_')       AS koef,
 m.start_date                             AS start_date
FROM   `match` m 
       LEFT JOIN `bettype` b 
              ON b.match_id = m.id 
		LEFT JOIN `choicetype` cho 
              ON cho.bet_id = b.id 
	    
WHERE m.id ='$val[mid]' AND b.name = 'Match Result' 
GROUP BY m.id
До тук добре. Почти всичко става перфектно, освен това че когато вкарам Group_concat(odd.koef SEPARATOR '_') AS oddkoef, ми взема три пъти първата стойност. и вместо да стане 1.20_2.30_3.50, то става 1.20_1.20_1.20.. Според това става защото не знам как да я вържа правилно с LEFT JOIN

П.С. Не знам колко е правилно да имам заявка във foreach, но засега само това ми идва на ум, за да успея да се справя.. Някакви идеи как да присъединя и koef полето от oddmove?
 
Аз съвсем се обърках.
Всичко си работи перфектно, освен нареждането на самата таблица и това става, защото примерно спада е във втората стойност на коеф-а а то винаги смята първата
Код:
1-ва стойност   2-ра стойност  3-та стойност 
1.50                           2.50                3.00 
2.00                            2,50               3,00
Кои са 3-те стойности? Имаш koef, oddkoef и кое е третото. Може би е по-добре да обясниш всичко отначало без ти да даваш заявки, защото те объркват още повече. Примерно дай основната структура на таблиците, и пиши на всеки ред какво очакваш да изведе.
 

Back
Горе