Retrieving the last level of categories in MySql - mysql

I have a category table in MySql database that holds the following data.
id name parent
-------------------------------------
1 Web development 0
2 Application development 0
3 Linux 0
4 Misc 0
5 Php 1
6 Mysql 1
7 Javascript 1
8 CSS 1
9 C plus plus 2
10 wxWidgets 2
11 Tutorials 3
12 My thoughts 4
13 Java 1
14 JSP 13
15 Spring 14
16 Spring 3.0 15
17 Spring 3.1 15
18 JSF 13
19 Oracle 0
20 Oracle 8i 19
21 Oracle 91 19
22 JSF 2.0 18
23 JSF 2.2 18
I need the following output.
5 Php 1
9 C plus plus 2
11 Tutorials 3
12 My thoughts 4
6 Mysql 1
7 Javascript 1
8 CSS 1
10 wxWidgets 2
22 JSF 2.0 18
23 JSF 2.2 18
16 Spring 3.0 15
17 Spring 3.1 15
20 Oracle 8i 19
21 Oracle 91 19
The result set should contain only the last level of each category. This can be done using a function in MySql. but is there a way to achieve this using an SQL query only?

please check it .. It will work
SELECT id, name, parent
FROM category
WHERE id NOT
IN ( SELECT parent FROM category )

Hows about this? It will query category and get the id of the rows that have a parent of 0 and then find each row that references that parent record.
select * from category as t1 where t1.parent in (select t2.id from category as t2 where t2.parent=0)

SELECT
c.id,
dr.ID,
dr.name,
dr.Parent
FROM category as c
inner JOIN (SELECT MAX(id) as ID, name , Parent FROM category WHERE parent != '0' GROUP BY parent) as dr ON dr.id = c.id
group by c.id
order by dr.Parent

Related

Mysql select result in one currency

I have to create a reports in one currency. I need to do query in MySQL without using PHP process. but unable to figure it out.
There is a table called currency_exchange_rate table as follows, (exchange rate in LKR to other currency).this table is updating like one record for each currency in LKR in every month
exchange_rates
id currency_id start_date exchange_rate
1 5 2017-01-2 155
2 4 2017-01-3 25
3 6 2017-01-3 53
4 5 2017-02-1 156
5 4 2017-02-1 24
6 6 2017-02-1 54
There is a project table as follows
pro_id name value currency_id status_id owner_id date
1 studio1 500 5 1 44 2017-01-20
2 lotus 120 5 1 42 2017-01-21
3 auro 300 4 2 45 2017-01-21
4 studio2 400 6 1 44 2017-01-22
5 holland 450 4 3 46 2017-02-05
6 studio3 120 4 3 47 2017-02-06
7 studio4 400 6 3 48 2017-02-06
how to generate reports in one currency(DKK but exchange rate in LKR) like status wise,monthly total, total by owner, etc..
and we have to consider currency id,currency to be convert and exchange rate for the month for those currency types to get relevant value for project row.
hope you are clear about my scenario. your help is much appreciated.
I don't need every report. just want a sql for convert values in project table using exchange rates table or status wise report as follows
status_id value_in_one_currency
1 xxxx
2 xxxx
3 xxxx
Try this:
SELECT A.status_id, A.`value` * B.exchange_rate `value_in_one_currency`
FROM project A JOIN exchange_rates B
ON A.currency_id=C.currency_id
AND DATE_FORMAT(A.`date`,'%m-%Y')=DATE_FORMAT(B.`start_date`,'%m-%Y');
See MySQL Join Made Easy for some insight.
This is what I finalize:
I took currency_id=5 as the final currency to be converted
SELECT A.*,C.exchange_rate AS DKK,D.exchange_rate AS LKR, (order_value * D.exchange_rate /C.exchange_rate ) AS `converted_value`
FROM projects A
LEFT JOIN exchange_rates C ON (DATE_FORMAT(C.start_date,'%Y-%m')=DATE_FORMAT(A.`date`,'%Y-%m') AND C.currency_id=5)
LEFT JOIN exchange_rates D ON DATE_FORMAT(D.start_date,'%Y-%m')=DATE_FORMAT(A.`date`,'%Y-%m') AND D.currency_id=A.currency_id

Table INSERT using While loop

While I've read many answers here, this is my first question on stackoverflow and I'm reasonably new to SQL. I am trying to use a WHILE loop (SQL Server 2008) to insert some records into a table. Here's the data I'm starting with:
SeasID FacilityID PL Zone Section Row FromSeat ToSeat
11 17 1 g2 cf a 1 5
32 18 14 w13 r2 c 10 12
I need to insert a row for every unique seat into a new table. Here's what I'd like to insert:
SeasID FacilityID PL Zone Section Row Seat
11 17 1 g2 cf a 1
11 17 1 g2 cf a 2
11 17 1 g2 cf a 3
11 17 1 g2 cf a 4
11 17 1 g2 cf a 5
32 18 14 w13 r2 c 10
32 18 14 w13 r2 c 11
32 18 14 w13 r2 c 12
I've tried many things and I don't think I understand loops very well yet. Any help you can provide would be great.
Quick and dirty (Change 1000 to the highest seat number possible. A Persistent Numbers table would help)
;WITH N(Number) AS (SELECT 1 AS Number UNION ALL SELECT Number + 1 FROM N WHERE Number < 1000)
SELECT TheTable.*, N.Number AS Seat
FROM TheTable
INNER JOIN N
ON ToSeat >= N.Number AND FromSeat <= N.Number
ORDER BY N.Number
OPTION(MAXRECURSION 1000)

retrieve all rows from the table grouped by condition

I have the following mysql table:
products
with a fileds:
id, product_group_id, internal_product_id, version, platform_id, name
1 12 12 1 30 Megacalculator
2 12 12 2 30 Megacalculator
3 16 17 1 30 Calculator
4 16 17 2 30 Calculator
5 16 18 0.1 40 Calculator Linux
6 20 19 2.1 30 Converter Windows
7 20 20 2.1 40 Converter Linux
8 30 24 0.1 30 Editor
I need to retrieve all rows from this table grouped by 'product_group_id' but with a different 'internal_product_id' inside of the group. Also, the rows count in each group must be equal to some special number(the value must be supplied into the query as an external parameter)
For example:
external parameter = 2, result:
product_group_id
16
20
external parameter = 1, result:
product_group_id
12
30
Please help me with this sql query.
Try that:
for parameter = 2
select `product_group_id` from products
group by `product_group_id`
having count(distinct `internal_product_id`) = 2
for parameter = 1
select `product_group_id` from products
group by `product_group_id`
having count(distinct `internal_product_id`) = 1
DEMO HERE
You can do this:
select product_group_id from products
group by product_group_id;
having count(internal_product_id) = 2;
Or you can get the information in a table:
select product_group_id, count(internal_product_id) from products
group by product_group_id;

How to get all rows based on single id

I have a table with a parent/child relationship structure.
There are 3 types of entities:
Actual Location (type=1)
Sub Group (type=10)
Head Group (type=100)
Example structure
id parent name type
28 0 Head Group 100
10 28 --Location 1 1
12 28 --Location 2 1
16 28 --Location 3 1
17 28 --Location 4 1
19 28 --Location 5 1
29 28 --Location 6 1
8 28 -Sub Group 1 10
11 8 --Sub Group 1 Location 1 1
30 28 -Sub Group 2 10
13 30 --Sub Group 2 Location 1 1
14 30 --Sub Group 2 Location 2 1
15 30 --Sub Group 2 Location 3 1
I want to be able to select all rows if 1d 28 (Head Group) is passed in.
I've tried to create a statement but I think this is beyond me. ANy help would be appreciated...
SELECT CGroup.id,
CGroup.parent,
CGroup.name,
CGroup.type
FROM Customer AS CGroup
INNER JOIN Customer AS CSubGroup
ON CSubGroup.parent_id = CGroup.id
WHERE CGroup.parent_id=28
You're making it too complicated. Keep it simple. Simple queries usually execute faster and have less bugs.
// first get all subgroups under the main group
subGroupIds = fetchField('
select group_concat(id)
from CGroup
where parent = 28
and type = 10
')
// then get everything
results = fetchRows('
select *
from CGroup
where parent = 28
or parent in (subGroupIds)
')
If you really want to do it "properly", I recommend implementing a Nested Set tree.

MySQL Select Last n Rows For List of ID'S

Fixture Table
uid home_uid away_uid winner date season_division_uid
1 26 6 6 2013-07-30 18
2 8 21 8 2013-06-30 18
3 6 8 8 2013-06-29 18
4 21 26 21 2013-05-20 18
5 6 26 6 2013-04-19 18
This table contains hundreds of rows.
Currently I have a query to select all the teams in a division, i.e.
SELECT team_uid
FROM Season_Division_Team
WHERE season_division_uid='18'
which lists the rows of team uid's i.e. [6,26,8,21,26].
Now for each of the unique team ids, I would like to return the last 3 winner values, ordered by the date column, that they were involved in (they could be an away_uid or home_uid).
So the returned value example would be:
team_id winner date
6 6 2013-07-30
6 8 2013-06-29
6 26 2013-04-19
26 6 2013-07-30
26 21 2013-05-20
26 6 2013-04-19
Any ideas? Thank you
Im not sure how to get it direct, a query like
select * from Season_division_Team where
`date >= (select min(`date`) from
(select `date` from season_division_team order by date desc limit 3))
and (home_uid = 6 or away_uid = 6)
Thats not going to be a good query. But only way i can think of currently
Its hard to get the 3rd largest value from SQL Example
the sub query is trying to get the date where the last win occured, and then getting all dates after that where the team played.
EDIT:
SELECT * FROM Season_Division_Team WHERE winner = 6 ORDER BY `date` DESC LIMIT 3
that sounds more like your latter comment