Need a way to make a MySQL query factor in or exclude condition in Where clause based on what conditions are specified or not specified - mysql

I use Chartio to create dashboards. I'm able to use variables with Chartio that can fill in sections of a MySQL query and then pump out a cool looking graph. I have a situation where I need a query that can have any combination of 3 variables X, Y, Z as shown below.
SELECT orderid
FROM orders
WHERE productcode IN (X) AND
status IN (Y) AND
date IN (Z);
I need to have the ability for the query to "determine" that if I only give it X, ignore Y and Z as a condition, for example. Or if I give it X and Y, ignore Z. I could give it any combinations of those three. By "ignore" I mean not use it as a condition in the WHERE clause.
Is this possible using OR? REGEXP? Wildcards? ...? I'm not very well versed in MySQL. Thanks in advance

if it sets the variable to an empty string when the user leaves the field out, you can write:
SELECT orderid
FROM orders
WHERE (X = '' OR productcode = X) AND
(Y = '' OR status = Y) AND
(Z = '' OR date = Z);

Related

Using MySQL GROUP_CONCAT Function like an ape

I have an issue with the function called GROUP_CONCAT.
My table:
"CUSTOMS
(
SHIPMENTS VARCHAR(255),
X INTEGER,
Y INTEGER,
Z INTEGER,
T INTEGER,
PRIMARY KEY (X,Y,Z)"
Now this is the query I try to run in general I know there will be a lot of syntax problems. I would be more then happy if you correct me and tell me what I do wrong
The query using the function
"SELECT GROUP_CONCAT(DISTINCT SHIPMENTS) AS CUSTOMSREQUEST
FROM CUSTOMS
WHERE (X,Y,Z) BETWEEN (?,?,?) AND (?,?,?) AND SHIPMENTS != (?)" {
I want to explain what I tried to do: basically I try to select a group_concat I use distinct method so the same shipments won't appear afterwards it I use AS CUSTOMREQUEST (dummy to return the string later.), after wards it FROM CUSTOMS < the table WHERE trying to get radius of X,Y,Z and at the end i try to filter specific string from the output...
This is the error I get:
Operand should contain 1 column(s)
It should return a single column as well...
What did I do wrong here? (I'm a newbie so please be bad ass with me thanks!)
The BETWEEN operator only takes one value on each side, and is checking the 2 values against 1 value/column. You should rewrite the query to something like:
SELECT GROUP_CONCAT(DISTINCT SHIPMENTS) AS CUSTOMSREQUEST
FROM CUSTOMS
WHERE x between ? and ? and y between ? and ? and z between ? and ? AND SHIPMENTS != (?)

Time differences between row in google big query

I'm currently attempting to calculate the timestamp differences between rows in google big query attached is the sample table I am using to test the code .
I am using this code
SELECT
A.row,
A.issue.updated_at,
(B.issue.updated_at - A.issue.updated_at) AS timedifference
FROM [icxmedia-servers:icx_metrics.gh_zh_data_production] A
INNER JOIN [icxmedia-servers:icx_metrics.gh_zh_data_production] B
ON B.row = (A.row + 1)
WHERE issue.number==6 and issue.name=="archer"
ORDER BY A.requestid ASC
Referenced from this question Calculate the time difference between of two rows
Rather than a JOIN, this is more naturally expressed using analytic functions. The documentation for analytic functions with standard SQL in BigQuery explains how analytic functions work and what the syntax is. As an example, if you wanted to take successive differences in x values where the order is determined by column y, you could do:
WITH T AS (
SELECT
x,
y
FROM UNNEST([9, 3, 4, 7]) AS x WITH OFFSET y)
SELECT
x,
x - LAG(x) OVER (ORDER BY y) AS x_diff
FROM T;
Note that to run this in BigQuery, you need to uncheck the "Use Legacy SQL" box under "Show Options" to enable standard SQL. The WITH T clause is simply setting up some data for the example.
For your specific case, you would probably want a query such as:
SELECT
row,
issue.updated_at,
issue.updated_at - LAG(issue.updated_at) OVER (ORDER BY issue.updated_at) AS timedifference
FROM `icxmedia-servers.icx_metrics.gh_zh_data_production`
WHERE issue.number = 6
AND issue.name = "archer"
ORDER BY requestid ASC;
If you want to determine differences in updated_at outside of just a single issue number, you could use a PARTITION BY clause as well. For example:
SELECT
row,
issue.name,
issue.number,
issue.updated_at,
issue.updated_at - LAG(issue.updated_at) OVER (
PARTITION BY issue.number
ORDER BY issue.updated_at) AS timedifference
FROM `icxmedia-servers.icx_metrics.gh_zh_data_production`
ORDER BY requestid ASC;

how can i select double field where different clause

can I use a query like this:
SELECT a AS x, a AS y
FROM table
WHERE x='1' and y='2'
how can I use such as that query...
You have to take main query in temp as follow:
SELECT temp.* FROM (SELECT a AS x, a AS y
FROM table) as temp WHERE temp.x = '1' AND temp.y = '2'
In general, you cannot use column aliases defined in the SELECT in the WHERE clause. This is true in all databases, not only MySQL. One method is to use a subquery (or CTE in databases that support them).
MySQL also extends the HAVING clause. This allows you to do:
SELECT a AS x, a AS y
FROM table
HAVING x ='1' and y = '2';
I assume that this question is made up, because the query can never return any rows.

How to set the value of a column to a sql query?

I have two tables x and y I want a column from x to be set to the average of a column from y grouped by a common column.
This what I'v done so far
update
set x.column2 = (SELECT AVG(NULLIF(column2,0))
FROM y group by column1)
on (x.column1 = y.column1)
And I want the value of x.column2 to be updated automatically whenever the value of any row of y.column2 changes.
Note: there is no column have the same name in the two tables.
UPDATE
x
SET
x.column2 = (SELECT AVG(NULLIF(column2,0))
FROM y
WHERE y.column1 = x.column1)
This will run the subquery once per row in x, but the subquery is limited to the rows in y where column1 matches the current x.column1.
For the curious, the internals of this are a bit deeper. In general, all queries (even sub-queries) return table-like objects ("relation" in relational-speak). If the result has only one row, it can be coerced into a 'row' ("tuple" in relational-speak). If the tuple has only one column, it can be further coerced into the value in that column. That is what is going on here. Additionally, no explicit "group by" is needed, because the WHERE clause limits the subquery to only the rows we want to sum, and so we take advantage of the implied 'group all rows' behavior (analogous to adding GROUP BY y.column1)
After your comment, I wanted to show how you would create a "View" for the same thing, which in MySQL means that the aggregated value is not actually 'stored', but calculated in real-time. This means it is never out of date as you insert into y.
CREATE VIEW vx AS SELECT column1, AVG(NULLIF(column2,0) as avg FROM y GROUP BY y.column1
You can then select from vx and in the background it will run that query.
You will need a trigger - see here.
In your case something like
CREATE TRIGGER name AFTER INSERT ON y FOR EACH ROW BEGIN [above statement] END
CREATE TRIGGER name AFTER UPDATE ON y FOR EACH ROW BEGIN [above statement] END
CREATE TRIGGER name AFTER DELETE ON y FOR EACH ROW BEGIN [above statement] END
I did not try out this, so no guarantee for being free of syntax errors (but should not be).

MySQL: Set variable and use in where clause in same query

I'm having some trouble setting a user variable in MySQL and using it in the same query. I found one or two other questions similar to this, but couldn't get any of their solutions to work in my case.
Here's my query, stripped down a bit. I replaced values and names and stuff for simplicity, and removed some irrelevant parts, but left the basic structure for some context. Not really relevant but fyi I'm using CodeIgniter's active record class to build the query.
SELECT * FROM (things, (SELECT #exp_time := IF(5 < 10, X, Y) as var))
JOIN more_things ON ...
WHERE ...
AND #exp_time < UNIX_TIMESTAMP()
AND `#exp_time` > 1319180316
ORDER BY ...
LIMIT 1 ...
The error I'm getting is: "Every derived table must have its own alias."
Would really appreciate any assistance. Thanks!
Your actual error is because (as the error message explains) you haven't specified an alias for your derived table, and this is required in MySQL (even if you never use the alias anywhere else in your query).
SELECT *
FROM
(
things,
(SELECT #exp_time := IF(5 < 10, X, Y) as var) AS your_alias
)
...
However you don't need variables here. Now that your derived table actually has a name you have a way to refer to your value without needing to store it an a variable.