I have table with this structure
ID | Parameter1 | Parameter 2 | Multiplication
1 | 1024 | 100 |
2 | 1200 | 200 |
3 | 1600 | 300 |
4 | 1900 | 400 |
I want to fill column Multiplication with combined string from Parameter 1 and Parameter 2
ID | Parameter1 | Parameter 2 | Multiplication
1 | 1024 | 100 | 1024_100
2 | 1200 | 200 | 1200_200
3 | 1600 | 300 | 1600_300
4 | 1900 | 400 | 1900_400
Help me please to create this SQLQuery
Using SQL then the following query should work..
Assuming the Param fields are ints use cast to make them strings
UPDATE Table1 SET Multiplication = CAST(Parameter1 AS VARCHAR(10)) + '_' + CAST(Parameter2 AS VARCHAR(10))
Else if they are already strings (e.g., varchar, text) just don't cast. I.e.,
UPDATE Table1 SET Multiplication = Parameter1 + '_' + Parameter2
Just change Table1 to the name of your table
An alternate for SQL Server is to add a column to handle this for you. It will automatically update the value if either parameter1 or parameter2 changes:
ALTER TABLE myTable
ADD myJoinedColumn AS CAST(Parameter1 AS VARCHAR(10)) + '_' + CAST(Parameter2 AS VARCHAR(10))
Or as #Scozzard mentions in his answer, if they are already strings:
ALTER TABLE myTable
ADD myJoinedColumn AS (Parameter1 + '_' + Parameter2)
For MySQL:
update Table1 set
Multiplication = concat(cast(Parameter1 as char), '_', cast(Parameter2 as char))
More about cast and concat in MySQL 5.0 Reference Manual.
update Table1 set Multiplication = CONCAT_WS('_',Parameter1,Parameter2)
update tablename
set Multiplication = convert(varchar, Parameter1) + '_' + convert(varchar, Parameter2)
Related
I have a MySQL table which has the following columns and records:
| Name | Total | GivenBy |
| ---- | -------- | ------------ |
| Z | 200 |['A','B','C'] |
| X | 240 |['A','D','C'] |
I would like to extract Record No. 1 on the basis of 3rd column where the SQL query would be like:
SELECT * FROM mytable WHERE GivenBy='B';
Is there a way I can loop through the list in third column and take out the respective string as required in the SQL WHERE clause in a single query?
Please note that I cannot add more columns in the table.
If you can please provide the query as MySQL compatible, I would really appreciate it.
The "array" you show isn't quite valid JSON, but if you use double-quotes instead of single-quotes, you can use JSON_TABLE() to do this:
CREATE TABLE MyTable
(
Name CHAR(1) PRIMARY KEY,
Total INT NOT NULL,
GivenBy JSON NOT NULL
);
INSERT INTO MyTable VALUES
('Z', 200, '["A","B","C"]'),
('X', 240, '["A","D","C"]');
SELECT Name, Total, g.Value
FROM MyTable
CROSS JOIN JSON_TABLE(GivenBy, '$[*]' COLUMNS(Value CHAR(1) PATH '$')) AS g;
+------+-------+-------+
| name | total | value |
+------+-------+-------+
| X | 240 | A |
| X | 240 | D |
| X | 240 | C |
| Z | 200 | A |
| Z | 200 | B |
| Z | 200 | C |
+------+-------+-------+
But the best choice is not to store "arrays" in MySQL. Store the values one per row in a second table.
You can use the "like" keyword with regex to match your requirements in the third column.
select * from table where givenBy like "%B%";
Something similar would work.
You need to run a script:
Retrieve the list of unique values in the GivenBy column using the following query:
SELECT DISTINCT JSON_EXTRACT(GivenBy, '$[*]') AS GivenByValues
FROM mytable;
Loop through the list of unique values, and for each value, run a query that uses that value in the WHERE clause:
SELECT *
FROM mytable
WHERE JSON_SEARCH(GivenBy, 'one', [current_value_from_loop]) IS NOT NULL;
I have a SQL table that looks something like this:
| ID | Value |
| --- | ----------------------------------------------------- |
| 1 | {"name":"joe", "lastname":"doe", "age":"34"} |
| 2 | {"name":"jane", "lastname":"doe", "age":"29"} |
| 3 | {"name":"michael", "lastname":"dumplings", "age":"40"}|
How can I using SQL select function, select only the rows where "age" (in value column) is above 30?
Thank you.
The column Value as it is it contains valid JSON data.
You can use the function JSON_EXTRACT() to get the the age and convert it to a numeric value by adding 0:
SELECT *
FROM tablename
WHERE JSON_EXTRACT(Value, "$.age") + 0 > 30;
See the demo.
I have a table that has many rows (between a few 1000s to a few million).
I need my query to do the following:
group results by the same part of the value in the field;
order by the biggest group first.
The table has mostly values that have only some part are similar (and i.e. suffix would be different). Since the number of similar values is huge - I cannot predict all of them.
Here is i.e. my table:
+--------+-----------+------+
| Id | Uri | Run |
+--------+-----------+------+
| 15145 | select_123| Y |
| 15146 | select_345| Y |
| 15148 | delete_123| N |
| 15150 | select_234| Y |
| 15314 | delete_334| N |
| 15315 | copy_all | N |
| 15316 | merge_all | Y |
| 15317 | select_565| Y |
| 15318 | copy_all | Y |
| 15319 | delete_345| Y |
+--------+-----------+------+
What I would like to see, something like this (the Count part is desirable but not required):
+-----------+------+
| Uri | Count|
+-----------+------+
| select | 4 |
| delete | 3 |
| copy_all | 2 |
| merge_all| 1 |
+-----------+------+
If you're using MySQL 5.x, you can strip the trailing _ and digits from the Uri value using this expression:
LEFT(Uri, LENGTH(Uri) - LOCATE('_', REVERSE(Uri)))
Using a REGEXP test to see if the Uri ends in _ and some digits, we can then process the Uri according to that and then GROUP BY that value to get the counts:
SELECT CASE WHEN Uri REGEXP '_[0-9]+$' THEN LEFT(Uri, LENGTH(Uri) - LOCATE('_', REVERSE(Uri)))
ELSE Uri
END AS Uri2,
COUNT(*) AS Count
FROM data
GROUP BY Uri2
Output:
Uri2 Count
copy_all 2
delete 3
merge_all 1
select 4
Demo on SQLFiddle
The format of the string makes it uneasy to parse it with string functions.
If you are running MySQL 8.0, you can truncate the string with regexp_replace(), then group by and order by:
select regexp_replace(uri, '_\\d+$', '') new_uri, count(*) cnt
from mytable
group by new_uri
order by cnt desc
If you're using MySQL 8.x, you can use REGEXP_REPLACE() to remove the numeric suffixes from select_XXX and delete_XXX, then group by the result.
SELECT REGEXP_REPLACE(uri, '_[0-9]+$', '') AS new_uri, COUNT(*) as count
FROM yourTable
GROUP BY new_uri
You can do as below and create a view and using the case expression + substr find which are 'select' and 'delete'.
Following the view you can query it with the count/group_by.
WITH view_1 AS (
SELECT
CASE
WHEN substr(uri, 1, 6) = 'select' THEN
substr(uri, 1, 6)
WHEN substr(uri, 1, 6) = 'delete' THEN
substr(uri, 1, 6)
ELSE uri
END AS uri
FROM
your_table
)
SELECT
uri,
COUNT(uri) as "Count"
FROM
view_1
GROUP BY
uri
ORDER BY count(uri) DESC;
Output will be
delete 5
merge_all 4
select 3
copy_all 3
I have the following tables:
UserPrivileges:
+--------+------+------+------+
| UserID | Col1 | Col2 | Col3 |
+--------+------+------+------+
| 1 | 0 | 1 | 1 |
| 2 | 0 | 0 | 1 |
| 3 | 1 | 0 | 0 |
| 4 | 1 | 1 | 0 |
+--------+------+------+------+
Data:
+--------+------+------+------+
| DataID | Col1 | Col2 | Col3 |
+--------+------+------+------+
| 1 | A | B | C |
| 2 | D | E | F |
| 3 | G | H | I |
| 4 | J | K | L |
+--------+------+------+------+
My question at its simplest form doesn't has anything to do with the Data table but I just explain it anyways so that I might be doing it the wrong way.
How would I select the Column names from UserPrivileges based on the value ? So that I can use the result in another query to select only those columns.
Something along these lines:
SELECT (COLUMNS_NAME_QUERY_FROM_UserPrivileges(UserID='#')) WHERE DataID = '#' FROM Data
Or I don't mind a better way to manage user Privileges for specific columns.
The answer depends upon your requirements for the result. Do you require a result with a consistent set of columns, regardless of user privs? If so, you could set the disallowed values to null (or some other special value) using a IF clause, e.g.,
SELECT IF (p.col1 = 0 THEN NULL ELSE d.col1) AS col1,
IF (p.col2 = 0 THEN NULL ELSE d.col2) AS col2,
IF (p.col3 = 0 THEN NULL ELSE d.col3) AS col3
FROM Data d,
UserPrivileges p
WHERE p.userId = '#'
AND d.DataId = '#'
Of course, the "special value" could be a problem, since you need a value that would never appear in the data. If you needed to know that difference between a null because the real value is null vs. null because it is a prohibited column then you can't use null.
Another approach would have you simple include the privilege indicator for each column appear in the result, and let your business logic use that to determine which values are visible to the user.
A very different approach would have the result set to contain only the allowed columns. In this case you'll need to build your sql statement dynamically. I don't know if you are doing this in a stored procedure or in a host language, but the basic idea is something like this:
string sqlCmd = "SELECT "
+ (SELECT (FIELDS_NAME_QUERY(UserID='#')
FROM USER_PRIVILEGES
WHERE userid='#')
+ FROM data d
execute sqlCmd
"execute" meaning whatever you have available to execute a string as a sql command.
more after clarification by OP:
Ok, you need sql function that returns a string that looks like "colname1, colname2, ...". The following resembles what it would look like in sql server. syntax
create function
FIELDS_NAME_QUERY (#userid int)
begin
select col1, col2, col3... INTO #col1priv, #col2priv, #col3priv FROM userPrivileges WHERE UserId = #UserId
declare #result varhcar(60)
set #result = ''
if (#col1priv = 1) #result = 'col1'
if (#col2priv = 1) #result = #result + ' ,col2'
if (#col3priv = 1) #result = #result + ' ,col3'
return #result
end
have not tried it, but something like this should work
SELECT (SHOW COLUMNS FROM table WHERE expr) FROM data WHERE DataID = '#'
Check this post for details - How can I get column names from a table in Oracle?
Let us know how you solve this...
I m stuck in a situation where I needed (column1 and column2) or (column1 or column3) from a table. So i implemented it as
select * from mytable
where column1=x and (column2=y or column3=z)
But it fetches me some unneccesory rows and by implementing as
select * from mytable
where (column1=x and column2=y) or (column1=x and column3=z)
It gives the result but i couldn't understand the diff between the two...please suggest
EDIT (added details)
Below I have explained my situation, Please check this,
Let me elaborate my situation :::
I have a table, say clientdetails(int id, var firstname, var mobileno, var landlineno) and I need to fetch those entries fetching values having unique (firstname and mobileno), or (firstname and landlineno). Either of the two mobileno or landlineno is mandatory.
so i wrote a query...
select id
from clientdetails
where firstname = 'pooja'
and (mobileno = mn or landlineno= ln )
and mobileno REGEXP '^[0-9]+$'
and landlineno REGEXP '^[0-9]+$'"
Now ln or mn can be anything and say ''. Since there are many instances where the firstname is "pooja" without a landlineno. So it fetches that entries too which has no landlineno but different mobileno..
When I use the following query
select id
from clientdetails
where (firstname = 'pooja' and mobileno = mn)
or (firstname = 'pooja' and landlineno= '' )
and mobileno REGEXP '^[0-9]+$'
and landlineno REGEXP '^[0-9]+$'"
It fetches me the required rows.
Please explain me the execution format of these queries
So as Alnitak pointed out in comments, There shouldn't be any difference - given three boolean variables
A, B, C, then A & (B | C) == (A & B) | (A & C)
Well, I have tested both queries with simple example below both queries gives same result.
create table emp_temp(id smallint(5),fname varchar(10),lname varchar(10));
insert into emp_temp values (1,'jon','kam'),(2,'ish','dalviv'),(3,'ctn','gado'),
(4,'jin','jain'),(5,'niraj','yadav');
select * from emp_temp;
mysql> select * from emp_temp;
+------+-------+--------+
| id | fname | lname |
+------+-------+--------+
| 1 | jon | kam |
| 2 | ish | dalviv |
| 3 | ctn | gado |
| 4 | jin | jain |
| 5 | niraj | yadav |
+------+-------+--------+
5 rows in set (0.00 sec)
Now comparing your two queries.
select * from mytable
where column1=x and (column2=y or column3=z)
select * from mytable
where (column1=x and column2=y) or (column1=x and column3=z)
Consider
column1 is id
column2 is fname
column3 is lname
mysql> select * from emp_temp
-> where id=1 and (fname='jon' or lname='yadav');
+------+-------+-------+
| id | fname | lname |
+------+-------+-------+
| 1 | jon | kam |
+------+-------+-------+
1 row in set (0.01 sec)
mysql> select * from emp_temp
-> where (id=1 and fname='jon') or ( id=1 and lname='yadav');
+------+-------+-------+
| id | fname | lname |
+------+-------+-------+
| 1 | jon | kam |
+------+-------+-------+
1 row in set (0.01 sec)
Both queries produces the same result.
Are any of the columns NULL?
true AND unknown => false
true OR unknown => true
etc.
I did not see if all combinations of NULL would cause the two expressions to differ, but it seems a possible culprit.