Understanding GROUP BY clause - mysql

SELECT a,b from <table_name> GROUP BY a,b,c.
Is the above a valid sql statement?

Not without a table name it is not. If it had a table name it would be valid, but probably not very useful.
Typically one would use GROUP BY clauses in conjunction with some aggregate function (SUM, COUNT, MAX, MIN, etc.) to derive some values related to the grouped fields.

Yes, that query is legal SQL. Whether it's useful SQL is another matter entirely.
The query
select a , b
from foo
group by a,b,c
Does the following:
groups the rows from the source table into distinct groups, 1 for each unique combination of columns a, b and c.
Each such group is then collapsed into a single row containing the grouping columns and the values of any required aggregate functions required by the query.
The resulting result set is then returned to the caller, tossing any unwanted columns (in this case, column c).
Since one of the grouping columns is discarded, the specified query is not guaranteed to be a set of unique rows. It might well contain duplicates. For instance, if group by came up with these groups to be returned:
A B C
- - -
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
The results set returned by the query would be
A B
- -
0 0
0 0
0 1
0 1
1 0
1 0
1 1
1 1
And so, not necessarily useful.

If you include a table name I guess you're asking if you can group by an unselected element c. Yes you can.

No - You need a table.
SELECT a,b FROM myTable GROUP BY a,b,c
where myTable is the table you are selecting from (which must have columns a,b and c).

No- because you didn't specify a table name. If you had, then yes, it's certainly valid for mysql, not sure about Oracle (which validates GROUPing very differently). But it doesn't make any sense...
a b c
0 0 0
0 0 1
0 1 0
0 1 1
applying the query to the table above will give:
0 0
0 0
0 1
0 1
And I don't see how that would be a meaningful result - if you don't want an aggregate value, then DISTINCT makes more sense - but gives a different result:
SELECT DISTINCT a, FROM `atable`
0 0
0 1
Maybe if you explained the real reason youwere asking the question we could make a more sensible attempt at answering it.

Related

return row even if all no value found in table mysql

I Have a select where I am trying to return a row even if there is nothing to be found from the select.
Here is the select
select
1 as risk_management,
0 as Borrow,
0 as Interest,
IFNULL(d.symbol,'E') as symbol,
IFNULL(d.Abbreviation,'EUR') as Abbreviation,
IFNULL(sum(round((a.amount_financed - a.amount_invested - a.amount_withdrawn) * i.average_rate / j.average_rate, 2)),0) as LendingOffers,
IFNULL( min(a.Interest),0) as InterestLend,
0 as VolumePerDay,
0 as LatestId,
0 as InterestLatestRealized,
0 as InterestBorrowLow,
IFNULL(max(a.Interest),0) as InterestLendHigh
from market_cap a
where ........more statements here...
But when I run this select I still get nothing returned.
I would like mysql to generate a row that has 0 for numbers and 'E' and 'EUR' if the value is missing, I thought IFNULL works for that after searching other stackoverflow but its not working in my case.
Since I don't have your data I cannot test the query for you, but I can demonstrate you the basic idea.
You need to create a buffer table with your default data as the main subselect of your query. In my example, it is called "dv" as in "default values".
The query which fetches the real values is also a subquery in the from clause. In my example, it is called "rv" as in "real values".
I use a left (outer) join on to join both select statements with a condition which is always true (on 1 = 1).
Therefore, when the query which fetches the real values cannot find any results, we can still use the values in the default table.
select
IFNULL(rv.risk_management, dv.risk_management) as risk_management,
IFNULL(rv.Borrow, dv.Borrow) as Borrow,
IFNULL(rv.Interest, dv.Interest) as Interest,
IFNULL(rv.symbol, dv.symbol) as symbol,
IFNULL(rv.Abbreviation, dv.Abbreviation) as Abbreviation,
IFNULL(rv.LendingOffers, dv.LendingOffers) as LendingOffers,
IFNULL(rv.InterestLend, dv.InterestLend) as InterestLend,
IFNULL(rv.VolumePerDay, dv.VolumePerDay) as VolumePerDay,
IFNULL(rv.LatestId, dv.LatestId) as LatestId,
IFNULL(rv.InterestLatestRealized, dv.InterestLatestRealized) as InterestLatestRealized,
IFNULL(rv.InterestBorrowLow, dv.InterestBorrowLow) as InterestBorrowLow,
IFNULL(rv.InterestLendHigh, dv.InterestLendHigh) as InterestLendHigh
from (
1 as risk_management,
0 as Borrow,
0 as Interest,
'E' as symbol,
'EUR' as Abbreviation
0 as LendingOffers,
0 as InterestLend,
0 as VolumePerDay,
0 as LatestId,
0 as InterestLatestRealized,
0 as InterestBorrowLow,
0 as InterestLendHigh
) as dv
LEFT JOIN (
select
risk_management,
Borrow,
Interest,
d.symbol,
d.Abbreviation,
sum(round((a.amount_financed - a.amount_invested - a.amount_withdrawn) * i.average_rate / j.average_rate, 2)) as LendingOffers,
min(a.Interest) as InterestLend,
VolumePerDay,
LatestId,
InterestLatestRealized,
InterestBorrowLow,
max(a.Interest) as InterestLendHigh
from market_cap a
where ........more statements here...
) AS rv
ON 1 = 1
Good succes and have a nice day Masnad Nihit

SQLite SELECT statement for column name where column has a value

What SQLite statement do I need to get the column name WHERE there is a value?
COLUMN NAME: ALPHA BRAVO CHARLIE DELTA ECHO
ROW VALUE: 0 1 0 1 1
All I want in my return is: Bravo, Delta, Echo.
Your request is not entirely clear, but you appear to be asking for a SELECT statement that will return not data but rather columns names, and not a predictable number of values but rather a number values that depend on the data in the table.
For instance,
A B C D E
0 1 0 1 1
would return (B,D,E) whereas
A B C D E
1 0 1 0 0
would return (A, C).
If that's what you're asking, this is not something that SQL does. SQL retrieves data from the table and an SQL result set always has the same number of columns per row.
To accomplish your goal, you would have to retrieve all columns that might have a value in the table and then, in your program code, check for the value in each column and accrue a list of column names that had values.
Also, consider what happens when there is more than one row to examine and the distribution of values differ. In other words, what's the expected result if the data looks like this:
A B C D E
- - - - -
0 1 0 1 1
1 0 1 0 0
[Also, note that all the columns in your example have values, some 0, some 1. What you really want is a list of column names where the column contains a value of 1.]
Finally, consider that your inability to easily get the results you need from your data might indicate a flaw in the data model you're using. For instance, if you were to structure your data like this:
TagName TagValue
------- --------
Alpha 0
Bravo 1
Charlie 0
Delta 1
Echo 1
you could then obtain your results with SELECT TagName FROM Tags WHERE TagValue = 1.
Furthermore, if 0 and 1 are really the only two possible values (indicating boolean "presence" or "absence" of the tag) then you could remove the TagValue column and the rows for Alpha and Charlie entirely (you'd INSERT a row into the table to add tag and DELETE a row to remove it).
A design along these lines seems to model your data more accurately and allows you to entire new tags to the system without having to issue an ALTER TABLE command.
http://sqlfiddle.com/#!9/1407e/1
SELECT CONCAT(IF(ALPHA,'ALPHA,',''),
IF(BRAVO,'BRAVO,',''),
IF(CHARLIE,'CHARLIE,',''),
IF(DELTA,'DELTA,',''),
IF(ECHO,'ECHO',''))
FROM table1

SAS : Eliminate duplicates if a condition is satisfied

I want to eliminate duplicates from a database, based on an identifier, an order and a condition.
More precisely, I have data with several observations. I have sometimes a condition that makes me want to keep that observation anyway (let fix it condition=1), but then also keep the observation with the same identifier even if this condition does not hold (condition=0).
But if I have for one identifier several observations where condition=0 then I want to elminate duplicates, with criterion being having the greatest order.
Without the condition I can do that
proc sort data=have;
by identifier descending order;
run;
proc sort nudopkey data=have;
by identifier;
run;
But how to incorporate my condition in this ?
Edit 1 : add a database example :
data Test;
input identifier $ order condition;
datalines;
1023 1 0
1023 2 0
1064 2 0
1064 1 0
1098 1 0
1098 1 1
;
Then I want to keep
1023 2 0
1064 2 0
1098 1 0
1098 1 1
Edit 2 : tried to precise my conditions
I presume you want to eliminate duplicates only when the condition for all records for an identifier is set to 0. In that case you want to keep the record with the maximum order and eliminate all other records with the same identifier.
Proc sql;
create table want as
select *
from test
group by identifier
having max (condition) ne 0
or order eq max (order)
;
Quit;
This will keep all rows for an Identifier where the maximum condition = 1,
or in the case of those where maximum condition = 0, select the row with the maximum order.
Is that what you want?
Some of this depends on how you define 'condition'. Is your condition easily verifiable on every record for that identifier? Then you can do something like this.
Evaluate the condition.
For records where it is true (you want to remove the duplicate), set flag=0. For records where it is not true, increment the condition flag by one.
If the condition is true for all records in that ID, all will have the same value (flag=0) and nodupkey on by identifier flag; will remove extras. If the condition is false for all records, those will not be removed. If it's true for some and false for some, and you want to remove only some of the records with that identifier (only the duplicates where it is true), then you have to make sure that either it's sorted to have all of the condition=true records at top, or have a separate flag counter that determines what value the flag will be (since it sometimes will go to 0 in the middle, so 0 0 0 1 2 3 0 4 5 6 is what you want, not 0 0 0 1 2 3 0 0 1 2 ).
Perhaps easier to see is to do it within a datastep. After sorting by identifier descending order:
data want;
set have;
by identifier descending order;
if (condition=true) and not (first.identifier) then delete;
run;
This will, again, work if either condition=true is always at the top, or if it's always consistent within one ID group. If it's inconsistent and mixed, then you need to keep track of whether you've kept one where it was true (assuming you want to), or it might delete all records where it is true; use a separate variable to keep track of how many you've kept. first.identifier will be 1/TRUE for the first record for that identifier only, not taking into account the condition. You could also create the flag, then sort by identifier flag descending order; and guarantee the condition=true are at the top (either by making flag=0 for true, or sorting by descending flag.)

Combining multiple columns into one- SQL Server 2008

I am trying to make one table value function in Sql Server. Here I have 3 columns and i want to merge them into one column lets say "new". This new column should show the name of 3 columns if they have value as 1.For example for row one it should display Isprod, for row 2 it should display IsCompetProd and so on.
IsProd IsCompetProd IsOther
1 0 0
0 1 0
0 0 1
1 0 0
Is there any way to do that?
Try like this
SELECT CASE WHEN IsProd=1 THEN 'IsProd'
WHEN IsCompetProd=1 THEN 'IsCompetProd'
WHEN IsOther=1 THEN 'IsOther'
END [New]
FROM table1
If I am getting what you want. Use a case statement. Try this:
SELECT
tbl.*,
(
CASE
WHEN IsProd=1
THEN 'IsProd'
WHEN IsCompetProd=1
THEN 'IsCompetProd'
WHEN IsOther=1
THEN 'IsOther'
ELSE 'None'
END
)AS newColumn
FROM
tbl

How to write query for this?

Hi friends I have a table like this
ID bid sub_bid cid sub_cid
1 0 2 1 0
2 5 0 3 0
3 3 0 0 4
4 2 0 4 0
on that table either (bid or sub_bid) OR (cid or sub_cid) will be null. I have to write a query for fetching like this..
if bid is zero then I have to take sub_bid or sub_bid is zero then I have to take bid
same incase of cid also.
How can I give this kind of a condition in my mysql query. any one can help me please.
thanks
Have a look at the CASE WHEN statement:
SELECT
CASE WHEN bid is NULL or bid = 0
sub_bid
ELSE
bid end
as abid
http://dev.mysql.com/doc/refman/5.0/en/case-statement.html
http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html
You can use the MySQL if statements for this. Check this