I want to Access temporarily created column
Please see below code example
Note: I have created one stored procedure for GP calculation It has
very long I want to simplify some calculations code.
SELECT 25 AS A,35 AS B, SUM(A+B) AS C
I know syntax is wrong but I want like below
| A | B | C |
| 25 | 35 | 60 |
You can either store values in the temp table.
SELECT A,
B,
Sum(A + B) C
FROM (SELECT 25 AS A, 35 AS B) AS TempTable;
Related
I want to create a PROCEDURE in MySQL that always returns x rows from a table, even when the table has less than x entries.
Like so:
+----+-------+
| id | value | CALL myProcedure USING(4);
+----+-------+ returns → a b c a
| 1 | a |
| 2 | b |
| 3 | c |
+----+-------+
Internally I store the last returned row (in this case it would be 'a') and on the next call the procedure should continue from there:
1st: CALL myProcedure USING(4) → a b c a
2nd: CALL myProcedure USING(3) → b c a
3rd: CALL myProcedure USING(7) → b c a b c a b
4th: CALL myProcedure USING(2) → c a
I tried it with UNION - this is what the 3rd call with x=7 would look like:
(
SELECT `value`
FROM `table`
LIMIT 1,7
)
UNION
(
SELECT `value`
FROM `table`
LIMIT 4
)
"give me as much as you can (up to 7) rows and start after row 1.
Then start over and give me the rest (7 - number of previous rows = 4)."
The first select returns b c and the second select returns a b c. Both selects together return b c a.
Now I am facing these problems:
1)UNION does not return the same row twice (all I would get from above call would be b c a)
2) At best I can "loop over my table" twice because there is only one union and I have no way of dynamically adding more unions. So even if I could get duplicate rows, it would only result in b c a b c and the remaining a b I expect will be missing.
How can I "loop" over my table multiple times? Is there anything better than UNION I could use?
EDIT (after solving my problem)
I followed cf_en's proposition to loop through the result set outside the database if the returned number of rows is less than expected. All other cases (those that only need one iteration) are covered by the procedure (using a simple UNION).
You can use UNION ALL to stop the union from removing duplicates. However, I wonder if the database is the best place to do the looping around. Could you return the distinct rows from the database and implement the looping logic in the calling code instead?
Suppose I have a database that contains two different types of information about certain unique objects, say their 'State' and 'Condition' to give a name to their classifiers. The State can take the values A, B, C or D, the condition the values X or Y. Depending on where I am sourcing data from, sometimes this database lacks entries for a particular pair.
From this data, I'd like to make a crosstab query that shows the count of data with a given State and Condition combination, but to have it still yield a row even when a given row is a 0. For example, I'd like the following table:
Unit | State | Condition
1 | A | X
2 | B | Y
3 | C | X
4 | B | Y
5 | B | X
6 | B | Y
7 | C | X
To produce the following crosstab:
Count | X | Y
A | 1 | 0
B | 1 | 3
C | 2 | 0
D | 0 | 0
Any help that would leave blanks instead of zeroes is fit for purpose as well, these are being pasted into a template Excel document that requires each crosstab to have an exact dimension.
What I've Tried:
The standard crosstab SQL
TRANSFORM Count(Unit)
SELECT Condition
FROM Sheet
GROUP BY Count(Unit)
PIVOT State;
obviously doesn't work as it doesn't raise the possibility of a D occurring. PIVOTing by a nested IIf that explicitly names D as a possible value does nothing either, nor does combining it with an Nz() around the TRANSFORM clause variable.
TRANSFORM Count(sheet.unit) AS CountOfunit
SELECT AllStates.state
FROM AllStates LEFT JOIN sheet ON AllStates.state = sheet.state
GROUP BY AllStates.state
PIVOT sheet.condition;
This uses a table "AllStates" that has a row for each state you want to force into the result. It will produce an extra column for entries that are neither Condition X nor Condition Y - that's where the forced entry for state D ends up, even though the count is 0.
If you have a relatively small number of conditions, you can use this instead:
SELECT AllStates.state, Sum(IIf([condition]="x",1,0)) AS X, Sum(IIf([condition]="Y",1,0)) AS Y
FROM AllStates LEFT JOIN sheet ON AllStates.state = sheet.state
GROUP BY AllStates.state;
Unlike a crosstab, though, this won't automatically add new columns when new condition codes are added to the data. It can also be cumbersome if you have many condition codes.
I have three tables.
The first table is like:
+----+----+----+
| id | x | y |
+----+----+----+
The second and third tables are like:
+----+----+----+----+----+----+----+----+----+----+----+----+
| id | Z1 | Z2 | Z3 | .. | .. | .. | .. | .. | .. | .. | Zn |
+----+----+----+----+----+----+----+----+----+----+----+----+
n is quite large, about 800-900.
I know it is quite ugly tables and database. But it is a raw data set and a learning set of a certain experiment. Please, just ignore it.
And a skeleton of a query is like:
'SELECT a.*, b.*, c.* \
FROM `test_xy` a, `test_1` b, `test_2` c \
WHERE a.id = b.id AND b.id = c.id'
What I concern is, the result with the query includes id field three times. I want id field to appear just one time at the front of the result.
I can do it by slicing the result table (by Python, MATLAB, etc.)
But, is there a better way to do this with a large number of columns? I mean, can id field of the second and third tables be excluded at the query stage?
The answer is the USING syntax: MySQL specific by the way. http://dev.mysql.com/doc/refman/5.5/en/join.html. Learn to use JOINs before you do anything else; putting the jon condition into the where clause is just plan wrong.
SELECT a.*, b.*, c.*
FROM `test_xy` a JOIN `test_1` b USING(`id)
JOIN `test_2` c USING(`id)
I want to return all rows that have a certain value in a column and have more than 5 instances in which a number is that certain value. For example, I would like to return all rows of the condition in which if the value in the column M has the number 1 in it and there are 5 or more instances of M having the number 1 in it, then it will return all rows with that condition.
select *
from tab
where M = 1
group by id --ID is the primary key of the table
having count(M) > 5;
EDIT: Here is my table:
id | M | price
--------+-------------+-------
1 | | 100
2 | 1 | 50
3 | 1 | 30
4 | 2 | 20
5 | 2 | 10
6 | 3 | 20
7 | 1 | 1
8 | 1 | 1
9 | 1 | 1
10 | 1 | 1
11 | 1 | 1
Originally I just want to insert into a trigger so that if the number of M = 1's is greater than 5, then I want to create an exception. The query I asked for would be inserted into the trigger. END EDIT.
But my table is always empty. Can anyone help me out? Thanks!
Try this :
select *
from tab
where M in (select M from tab where M = 1 group by M having count(id) > 5);
SQL Fiddle Demo
please try
select *,count(M) from table where M=1 group by id having count(M)>5
Since you group on your PK (which seems a futile excercise), you are counting per ID, whicg will indeed always return 1.
As i explain after this code, this query is NOT good, it is NOT the answer, and i also explain WHY. Please do not expect this query to run correctly!
select *
from tab
where M = 1
group by M
having count(*) > 5;
Like this, you group on what you are counting, which makes a lot more sense. At the same time, this will have unexpected behaviour, as you are selecting all kinds of columns that are not in the group by or in any aggregate. I know mySQL is lenient on that, but I don;t even want to know what it will produce.
Try indeed a subquery along these lines:
select *
from tab
where M in
(SELECT M
from tab
group by M
having count(*) > 5)
I've built a SQLFiddle demo (i used 'Test' as table name out of habit) accomplishing this (I don't have a mySQL at hand now to test it).
-- Made up a structure for testing
CREATE TABLE Test (
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
M int
);
SELECT id, M FROM tab
WHERE M IN (
SELECT M
FROM Test
WHERE M = 1
GROUP BY M
HAVING COUNT(M) > 5
)
The sub-query is a common "find the duplicates" kind of query, with the added condition of a specific value for the column M, also stating that there must be at least 5 dupes.
It will spit out a series of values of M which you can use to query the table against, ending with the rows you need.
You shouldn't use SELECT * , it's a bad practice in general: don't retrieve data you aren't actually using, and if you are using it then take the little time needed to type in a list of field, you'll likely see faster querying and on the other hand the code will be way more readable.
I have a table, called gcrunarrays with the columns {run_id, time_id, co2}. I have several thousand runs with distinct run_id's, each with 58 time-dependent values for co2. I have a procedure to obtain the median co2 of all runs at a given time. Now, I need a select statement that will obtain the medians for each time. So far, I have
select DISTINCT A.time_id, M.co2 from gcrunarrays A, call getMedian(1, A.time_id) M
GO
Which gets a syntax error. I am fairly new at SQL and I'm working in MYSQL. I've tried about a dozen different ways of wording this statement but now I'm at the point where I feel like I've done something inherently wrong. I think it might work better if median were a function but I'm not sure even how to get the median without using a select statement. Any suggestions are greatly appreciated.
For greater clarification:
Table gcrunarrays
run_id | time_id | co2
1 | 1 |
1 | 2 |
...
1 | 58 |
2 | 1 |
...
2 | 58 |
3 ...
Median Procedure
CREATE PROCEDURE getMedian (IN e INT, t INT)
BEGIN
SELECT count(*), x.co2
FROM (SELECT B.exp_id, A.* FROM gcRunArrays A JOIN gcRuns B ON A.run_id=B.run_id WHERE B.exp_id=e and A.time_id=t) x,
(SELECT B.exp_id, A.* FROM gcRunArrays A JOIN gcRuns B ON A.run_id=B.run_id WHERE B.exp_id=e and A.time_id=t) y
GROUP BY x.co2
HAVING SUM(SIGN(1-SIGN(y.co2-x.co2))) = CEILING((COUNT(*)+1)/2);
END
GO
Use a temp table can easily solve the issue.
And it is not possible to use procedure results as table directly.
Can a stored procedure/function return a table?