mysql json_extract dynamic position - mysql

SELECT id, JSON_EXTRACT(column,'$.parent[3].child') AS child FROM table
WHERE JSON_EXTRACT(column,'$.parent[3].child') IN (1)
this is my sql query. i have a also column jsonlength how can i connect this 2 columns in one query ? i want to change 3 to dynamic number given in jsonlength
for example:
SELECT id, JSON_EXTRACT(column,'$.parent['jsonlength'].child') AS child FROM table
WHERE JSON_EXTRACT(column,'$.parent['jsonlength'].child') IN (1)
but this query not working.

You need to form the JSON path with string concatenation. In MySQL, this is done with the CONCAT() function.
SELECT id, JSON_EXTRACT(column, CONCAT('$.parent[',jsonlength,'].child')) AS child FROM table
WHERE JSON_EXTRACT(column,CONCAT('$.parent[',jsonlength,'].child')) IN (1)

Related

SQL SELECT everthing with value 5 but not specify from which column

I have tried to select something with SQL, and I've a problem with it.
What I want:
SQL SELECT * FROM table WHERE ? = '5';
Select everything which = 5, BUT not specify from which column.
Example:
From this ""database"", you should receive the 1st and the last row.
Is that possible?
You have to list the columns but you can use in. The where clause looks like:
where 5 in (price, height)
Note: This assumes that the columns have the same type. You could get type conversion errors if they are not.
Also, given the names of the column and the data, I assume that the columns are stored as numbers. Hence, I dropped the single quotes around 5. If they are really strings, then use the single quotes.
you need to add a condition to your query with or keyword so if any of them match the row will be shown as a result
SELECT * FROM tablename WHERE price =5 or height= 5
better you list your columns by name instead of using * after SELECT

SQL: Order by a list of foreign_key numbers

A simplified example:
I have a SQL table called things. Things by themselves have an id and a name. Things are part of a tree, e.g. a thing can have a parent; Exactly how to this is stored is not important, important is however that it is possible to obtain a list of thing ids from the root node to the current thing.
I have another table, called properties. A property has a thing_id column, a name column and a value column.
I now want, for the current thing, to obtain all properties, ordered by thing_id, in order of the paths from root thing to current thing.
e.g., if the current thing is nested like this: Root(1) > Vehicle(4) > Car(2) > Hybrid(3), I would want the list of properties be returned with the properties that have a thing_id==1 first, followed by the ones with thing_id == 4, then thing_id==2 and finally thing_id==3.
How can this be done using SQL? (without using N+1 selects)
In SQL this can be achieved with use of recursive query. Here is an example
DECLARE #item as varchar(10)
with CTE (main_part, sub_part, NestingLevel)
as
(
select main_part, sub_part, 1 from tblParts
where main_part = #item
union all
select tblParts.main_part, tblParts.sub_part, (NestingLevel + 1) from tblParts
inner join CTE on tblParts.main_part = CTE.sub_part
)
select * from CTE
In order to address this in MySQL you can try temporary table approach. Here is a good example of it: How to do the Recursive SELECT query in MySQL?

Running a SQL SELECT statement against a MYSQL column of SET type

I'm trying to run a SQL SELECT statement against a column that is of type SET. The table is called myTable and the columns in myTable are called base_props and names. The base_props column is of type SET. The values in base_prop are vb,nt, cnt,poss and loc. So I would like to SELECT entries from the column 'name' where base_props have both the values, vb and poss. The results I'm looking to get may have values other than just vb and poss. So to be clear I would like to select all entries that have the values vb and poss regardless if they have other values as well. I've tried the following SQL queries but I can't get the desired results.
SELECT name from myTable WHERE base_props = 'vb' AND base_props = 'poss'
That query returns an empty result set. I've tried using FIND_IN_SET() and IN() but I couldn't get anywhere with that. I've written SQL statements before but never had to deal with columns that are type SET. Any help is appreciated.
The only thing I can come up with is using the LIKE keyword:
SELECT name FROM myTable WHERE (base_props LIKE '%vb%' AND base_props LIKE '%poss%');
This will make sure both vb and cnt are in the base_props column. Of course you can use cnt, nt and loc in there, or any number of base_props values in the sql, just add more AND statements.
OR as a deleted answer by samitha pointed out, you can use FIND_IN_SET:
SELECT name from myTable WHERE FIND_IN_SET('vb', base_props) AND FIND_IN_SET('poss', base_props);
Comment (by spencer7593): "both of these work, but there is a slight difference. The LIKE operator will actually match any member that includes the search string anywhere in a term; the FIND_IN_SET function will only match an exact member. It's also possible to search for members in set by the order they appear in the SET definition, using the MySQL BITAND operator: for example, to match the 1st and 4th members of the set: WHERE base_props & 1 AND base_props & 8". So for example, if you have 'a' and 'aaa' in your set, then using the LIKE "%a%" method will also return rows containing 'aaa'.
Conclusion: use the FIND_IN_SET solution since it will work for all cases.
FIND_IN_SET return index, Try this
SELECT name from myTable WHERE FIND_IN_SET(base_props, 'vb') > 0 AND
FIND_IN_SET(base_props, 'poss') > 0

SELECT in mysql using column number instead of name

Is there any way to do something like :
SELECT * FROM TABLE WHERE COLUMN_NUMBER = 1;
?
No, you can't. Column order doesn't really matter in MySQL. See the below question for more details.
mysql - selecting values from a table given column number
If your table has a column named COLUMN_NUMBER and you want to retrieve rows from the table where that column contains a value of '1', that query should do the trick.
I suspect that what you are trying to do is reference an expression in the select list with an alias. And that is not supported. An expression in the WHERE clause that references a column must reference the column by name.
We can play some tricks with inline views, to give an alias to an expression, but this is not efficient in terms of WHERE predicates, because of the way MySQL materializes a derived table. And, in that case, its a name given to the column in the inline view that has to be referenced in the outer query.
How I did it:
I'm trying to take (last 3 values of) column number 4 in sometable.
set #mydb=(SELECT DATABASE());
set #mycol=(select COLUMN_NAME from information_schema.columns where
table_schema=#mydb and table_name='sometable' and ordinal_position = 4);
SELECT Date,#mycol FROM sometable ORDER BY Date DESC LIMIT 3;
Of course, if Database name is known, first line could by whiped and #mydb replaced by real database name.
You can do this trick
Example:
$query="select * from employee";
$result=mysql_query($query);
$meta=mysql_fetch_field($result,0) // 0 is first field in table , 1 is second one ,,, etc
$theNameofFirstField=$meta->name; // this well return first field name in table
// now you can use it in other query
$seconQuery="select $theNameofFirstField from employee";

Pass number as a column name in select statement of Sql

My query is like this
select 5 from mytable_name;
Then the output is like column name 5 and the value is 5 printing as many max number of rows exists in that table.
Can anybody tell the reason why this query is working like this?
Can anybody tell the reason why this query is working like this?
You are selecting a string literal value '5' for each row in your table:
select 5 from mytable_name;
And this works fine. Because in the SELECT statement you can select:
Column reference,
Literal value like in your case.
Function.
value expression.
Select expression.
As defined by the standard SQL1:
Update:
However, If you have a column with a name is a number like in your case, you have to escape it in order to select the values in it like so:
SELECT `143` FROM Table1;
This will select all the rows in the column 143.
But, this:
SELECT 143 FROM Table1;
Will select the string literal 143 for each row found in the table.
Note that: If possible, try not to name these columns this way, it is recommended and a best practice, not to do this.
SQL Fiddle Demo
Update 2:
Note that, if you select 143 or '143', or even "143" this will select the literal value 143 not the column date. The following are the same:
SELECT 143 FROM Table1;
SELECT '143' FROM Table1;
SELECT "143" FROM Table1;
All these SELECTs won't select the data in the column, They will select the literal value 143 not the column data. See this demo:
Demo
You have to escape the column name with the two:
``
Like this:
SELECT `143` FROM table1;
Not:
SELECT '143' FROM table1'
Like what I did here:
The right Demo
1Image From: SQL Queries for Mere Mortals
from mytable
will select all rows from your table if there is no where condition that shrinks that result. and
select 5
will select the constant number 5 for every record. If you use a column name in the select part then that value will be selected for every record.
The DB engine will name the result 5 because it automatically generates a column name and 5 is the logical name for that.
You want 'SELECT * FROM mytable_name LIMIT 0,5' perhaps?
Since you don't have anything in your where clause, it is selecting all the rows from your table. The fact that you don't select any of the columns is irrelevant - you'll still get a result for each row in the table.
With the command select 5 ... you are viewing a fixed value. Same thing you run the following command: select "test", you will be displaying a fixed string.
Using ... from mytable_name you're looking for all record of this table.
With this we can conclude that for each record in the table mytable_name shows you the fixed value "5".