I rewrite a stackoverflow question:
I have a table and data like this:
ID | Name | Type
1 Apple A
2 Boy A
3 Cat B
4 Dog C
5 Elep C
6 Fish C
What SELECT I must use to obtain this result:
4 Dog C
5 Elep C
6 Fish C
1 Apple A
2 Boy A
3 Cat B
I dont want this one ...:
select ID, Name, Type from TABLE where GROUP BY Type order by count(*) desc;
...whith this result:
4 Dog C
1 Apple A
3 Cat B
Thanks
The issue you've got is the grouping command affects the values you are trying to select. One way around this is to derive the count (typetotal) for each type, in its own table like:
SELECT
Type,
COUNT(*) AS typetotal
FROM
TABLE
GROUP BY
Type
We are now able to link the Type to the typetotal to your new SELECT query using the INNER JOIN command, allowing you to sort the query as shown below:
SELECT
TABLE.ID,
TABLE.Name
TABLE.Type,
FROM
(
SELECT
Type,
COUNT(*) AS typetotal
FROM
TABLE
GROUP BY
Type
)
AS tblTypeCount
INNER JOIN
TABLE
ON
TABLE.Type = tblTypeCount.Type
ORDER BY
tblTypeCount.typetotal DESC
I hope I've explained this in a way that makes sense, if you need any clarification, or have any suggestions let me know.
Related
I have a table in which I want to compare an ID column with another column in the same table.
This is my table
ID | Name | BossID
1 John 3
2 Max 4
3 Peter 4
4 Alex 5
For example I want to use
select * from mytable where ID = BossID
and I expected to get that Peter is the Boss of John and Alex is the Boss of Max and Peter, but when I use it this way, I dont get any info on the query...
Any idea to get it?
The expected query result are:
ID | Name | BossID
1 John 3
2 Max 4
3 Peter 4
seems like you want the list of employees who their boss exists in the list as well:
select *
from mytable
where bossid in (select id from mytable);
to get the boss name :
select t.ID, t.Name, b.Name as BossName
from mytable t
join mytbale b
on t.bossid = b.id
you can use left join to return all the employees in the list
I got two tables. Table one with 3 category columns. Table 2 with 2 category columns. I try to write a query that compare this category columns and shows me the data wich is in one of the threee columns of table 1, but not in one of the two columns of table 2.
e.g.
table 1
ID product cat1 cat2 cat3
10001 product a A B C
10001 product a D E NULL
10001 product a F G H
10002 product b B C D
... ... ... ... ...
table 2
ID product cat1 cat2
10001 product a D E
10001 product a D F
10001 product a G A
10002 product b A C
... ... ... ... ...
The output of the query should look something like that:
product_id not_in_cat
10001 B
10001 C
10001 H
10002 B
10002 D
But i dont know how i can realize it. I tried to do this with a subquery and the "NOT IN" command. But this way i got many subqueries, for each combination of t1.cat1 - t2.cat1, t1.cat2 - t2.cat2, and so on.
And this way i got only the cats which are not in the same row.
Maybe someone can help me to figure out, which way is the best to achieve the desired result.
The query is performed on a MS SQL Server with a openquery to a MySQL and a oracle db server. But i think its more a logic problem.
I think you should "normalize" the data and do the equivalent of a full outer join using union all and group by. This looks like:
select id, cat
from (select id, cat1 as cat, 1 as which from table1 union all
select id, cat2 as cat, 1 as which from table1 union all
select id, cat3 as cat, 1 as which from table1 union all
select id, cat1 as cat, 2 as which from table2 union all
select id, cat2 as cat, 2 as which from table2
) ic
where cat is not null
group by id, cat
having min(which) = max(which);
This finds the categories that are in only one of the tables. Note: If you know that there are no duplicates in either table, then having count(*) = 1 also works.
And, if you want to know the table where the category is present, then ask another question. That is a bit different from the question that you did ask.
I have a table like this
itemid | propertyname | propertyvalue
___________|______________|_______________
1 | point | 12
1 | age | 10
2 | point | 15
2 | age | 11
3 | point | 9
3 | age | 10
4 | point | 13
4 | age | 11
I need a query to select all items where age greater than 10 and point less than 12.
I tried
`select itemid from table where (propertyname="point" and propertyvalue < 12)
and (propertyname="age" and propertyvalue >10)`
It gives no results. How can I make it work?
you can use an inner join
SELECT
a.itemid
FROM
yourTable a
INNER JOIN
yourTable b
ON
a.itemid=b.itemid
AND a.propertyname='point'
AND b.propertyname='age'
WHERE
a.propertyvalue<12
AND b.propertyvalue>10
ok so in table a youre lookin for all items with the name point and a value smaller 12 and in table b youre looking for all items with the name age and a value greater 10. Then you only have to look for items, which are in both tables. For this you connect the two tables over the itemid. To connect tables you use the join. Hope this will help you to understand. If not ask again :)
To join a table to itself in the same query you can include the table twice in the FROM clause, giving it a different alias each time. Then you simply proceed with building your query as if you were dealing with two separate tables that just happen to contain exactly the same data.
In the query below the table example is aliased as a and b:
SELECT a.itemid
FROM example a, example b
WHERE a.itemid = b.itemid
AND a.propertyname = 'point'
AND a.propertyvalue < 12
AND b.propertyname = 'age'
AND b.propertyname > 10
Try It:
SELECT itemid FROM test_table WHERE propertyname="point" AND propertyvalue < 12 AND itemid IN(SELECT itemid FROM test_table WHERE propertyname="age" AND propertyvalue >10)
http://sqlfiddle.com/#!9/4eafc6/1
PLs Try this
select itemid from table where (propertyname="point" and propertyvalue < 12)
or (propertyname="age" and propertyvalue >10);
Here's one idea...
SELECT item_id
, MAX(CASE WHEN propertyname = 'point' THEN propertyvalue END point
, MAX(CASE WHEN propertyname = 'age' THEN propertyvalue END age
FROM a_table
GROUP
BY item_id
HAVING age+0 > 10
AND point+0 < 12;
You can use an inner join. Meaning, it's like you're going to work with 2 tables: the first one you're going to select the name="age" and val>10, and the second one is where you're going to select name="point" and val<12.
It's like you're creating an instance of your table that doesn't really exist. It's just going to help you extract the data you need at the same time.
I need to merge to queries together. This is a simple task that I do a lot, but this time I have something a little bizarre. The 2 queries I'm merging are from the same table and the same column.
Here is a basic concept of my original table:
|id|content|
0 | a
1 | b
2 | c
3 | d
I want my query to return everything once. Then again where I selected it. So SELECT * FROM 'my_table' and SELECT * FROM 'my_table WHERE id IN (1,2) I want it to return something like this.
a
b
a
b
c
d
Edit: #dnoeth commented the right answer. I didn't read it right the first time though.
I found the answer I was looking for. I just didn't know how to word was I was looking for.
What I needed to do was unite 2 queries on the same table.
You do this by simply using UNION ALL instead of union
So here is an example in mysql.
SELECT * FROM my_table UNION ALL SELECT * FROM my_table WHERE id IN (1,2)
Then if you are using Laravel's eloquent like I am use this.
$query = Class::whereIn('id', $array);
Class::where('id','>=',0)->unionAll($query)->get();
Well since you're not really precise on what the result should be, you might do like this:
select t1.val
from tableT t1
join tableT t2 on t1.id=t2.id or t1.id+1=t2.id
where t1.id<=2 and t2.id<=2 or t1.id>=3
Should yield:
a
b
b
c
c
d
Just use the clause UNION, you can "join" several SELECTs with the only restiction that they have same result columns. Your example will be:
(SELECT * FROM 'my_table')
UNION
(SELECT * FROM 'my_table WHERE id IN (1,2))
And you will get:
|id|content|
0 | a
1 | b
2 | c
3 | d
1 | b
2 | c
More details:
http://dev.mysql.com/doc/refman/5.7/en/union.html
PS:
The default behavior for UNION is that duplicate rows are removed from the result. With the optional ALL keyword, duplicate-row removal does not occur and the result includes all matching rows from all the SELECT statements.
I have 3 Tables
campaign1 (TABLE)
id campaign_details
1 'some detail'
campaign2 (TABLE)
id campaign_details
1 'some other detail'
campaign_list (TABLE)
id campaign_table_name
1 'campaign1'
2 'campaign2'
Campaign list table contains the table name of the two tables described above. I want to Select from the Campaign List table and get the record count using the table name i get from this select
For eg.
using select i get campaign1(Table name). Then i run select query on campaign1 to count number of records.
What i'm doing right now is .
-Select from campign_list
-loop through all campaign_table_names and run select query individually
Is there a way to do this using a single query
something like this
select campaign_name,(SELECT COUNT(*) FROM c.campaign_name) as campcount from campaign_list c
SQLFiddle : http://sqlfiddle.com/#!9/b766d/2
It's not possible inside a single query to build it dynamically but it's possible to cheat. Especially if there are only two linked tables.
I've listed two options
left outer join both tables
select campaign_name,
coalesce(c1.campaign_details, c2.campaign_details)
from campaign_list c
left join campaign1 c1 using (id)
left join campaign2 c2 using (id);
union all two different selects
select campaign_name,
campaign_details
from campaign_list c
join campaign1 c1 using (id)
union all
select campaign_name,
campaign_details
from campaign_list c
join campaign2 c2 using (id);
sqlfiddle
Combine your campaign tables to 1 table and add an column named 'type' (int).
campaign_items tables:
item_id item_details item_type
1 'some detail' 1
2 'some detail' 1
3 'some other detail' 2
4 'some other detail' 2
campaign_lists table
campaign_id campaign_name
1 'campaign1'
2 'campaign2'
Then you can use the following select statement:
SELECT campaign_name, (SELECT COUNT(*) FROM campaign_items WHERE item_type = campaign_id) as campaign_count
FROM campaign_lists
Oops, writing took me so long that you got this answered by Colin Raaijmakers already. Well, I'll post my answer anyway in spite of being more or less the same answer. Maybe my elaboration helps you see the problem.
Your problem stems from a bad database design. A database is made to order data and its relations. A CD database holds albums, songs, artists, etc. A business database may hold items, warehouses, sales and so on. Your database holds table names. [... time for thinking :-) ]
(When writing a DBMS you would want to store table names, column names, constraints etc., but I guess I am right supposing that you are not writing a new DBMS.)
So create tables that deal with your actual data. E.g.:
campain_type (id_campain_type, description, ...)
campain (id_campain, id_campain_type, campain_date, ...)
campain_type
id_campain_type description
1 Type A
2 Type B
3 Type C
campain
id_campain id_campain_type date
33 1 2015-06-03
85 2 2015-10-23
97 2 2015-12-01
query
select
ct.description,
(select count(*) from campain c where c.id_campain_type = ct.id_campain_type) as cnt
from campain_type ct;
result
description cnt
Type A 1
Type B 2
Type C 0