I'm trying to create a data abstraction in SQL where I can choose the quarter I want to look at for my employee info. Right now I'm using the naming system Q1_P1_N for "Quarter 1 Project 1 name" and Q1_P1_W is "...project 1 weight." Employees can work on multiple projects.
So far what I have is:
CREATE PROCEDURE effort_lookup4(IN proj_name VARCHAR(20), IN quarter INT(1))
BEGIN
SET #Qx_P1_N = CONCAT('Q', quarter, '_P1_N');
SET #Qx_P2_N = CONCAT('Q', quarter, '_P2_N');
SET #Qx_P1_W = CONCAT('Q', quarter, '_P1_W');
SET #Qx_P2_W = CONCAT('Q', quarter, '_P2_W');
SET #var1 = (SELECT sum(#Qx_P1_W) FROM table_test WHERE #Qx_P1_N = proj_name);
SET #var2 = (SELECT sum(#Qx_P2_W) FROM table_test WHERE #Qx_P2_N = proj_name);
My problem is that whenever I call a query with #Qx_P1_N or #Qx_P1_W I'm not actually passing the correct query in and I can't figure out what I'm doing wrong. This should be pretty easy I'm just new to using SQL.
Here's an example of what the table looks like, except it carries on into Q2_P1_N and so on through the quarters:
+------+---------+---------+---------+---------+
| EMPID| Q1_P1_N | Q1_P2_N | Q1_P1_W | Q1_P2_W |
+------+---------+---------+---------+---------+
| 1000 | ProjA | ProjB | 0.50 | 0.50 |
| 1001 | ProjA | NULL | 1.00 | NULL |
| 1010 | ProjB | NULL | 1.00 | NULL |
| 1011 | ProjA | ProjB | 0.50 | 0.50 |
+------+---------+---------+---------+---------+
Thanks
To do what you want with your existing data structure requires that you use prepared statements (you build your desired SELECT statement as a string that you then PREPARE and EXECUTE).
However, you will probably find it easier to change your data structure:
+------+---------+---------+--------+
| EMPID| quarter | project | weight |
+------+---------+---------+--------+
| 1000 | 1 | A | 0.50 |
| 1000 | 1 | B | 0.50 |
| 1001 | 1 | A | 1.00 |
| 1010 | 1 | B | 1.00 |
| 1011 | 1 | A | 0.50 |
| 1011 | 1 | B | 0.50 |
+------+---------+---------+--------+
On your select statement you have a variable in the field that should be the column name in the table. You will need to switch the #Qx_P1_W for Q1_P1_W.
Related
Let's say I have a table like this:
| id | mtime |
...
| 101 | 12:00:00 |
| 102 | 12:01:00 |
| 103 | 12:03:00 |
| 104 | 12:07:00 |
| 105 | 12:08:00 |
| 106 | 13:00:00 |
...
Is there a way to query the table (range 12:00:00-13:00:00) to get a set with missing values like this:
| mtime |
| 12:02:00 |
| 12:04:00 |
| 12:05:00 |
| 12:06:00 |
| 12:09:00 |
| 12:10:00 |
...
| 12:59:00 |
or at least first empty occurance:
| mtime |
| 12:02:00 |
or last consecutive value, that breaks the chain:
| mtime |
| 12:01:00 |
I was thinking about using ADDTIME(time, '00:01:00') somewhere in the query but I can't figure it out. Right now I barely believe it's achievable without more complex coding and multiple queries, but I hope I'm missing something.
Generate a table (TABLE2) which have time of a full day (if u really need at any date),
and write your query like this
SELECT TABLE2.mtime FROM TABLE2
LEFT JOIN TABLE1 ON TABLE1.mtime = TABLE2.mtime
WHERE TABLE1.mtime IS NULL
also add condition for maximum and minimum time check, because TABLE2 have all dat times.
I have two tables. One (let's call it a) is currently a link table with data in like this
| c_id | t_id |
|-------|-------|
| 1 | 8 |
| 1 | 9 |
| 2 | 8 |
| 3 | 8 |
| 4 | 9 |
and another (t) with data like this
| id | code | value |
|-------|-------|-------|
| 1 | AB | 0.9 |
| 2 | BC | 0 |
| 3 | IM | 0 |
| 4 | MC | 0 |
| 5 | VI | 0 |
| 6 | BC | 0.9 |
| 7 | MC | 2.5 |
| 8 | VI | 2.5 |
| 9 | BC | 2.5 |
t_id in table a is a foreign key mapping onto id in table t, which is an auto incremented ID.
Due to functionality changes, I now want the data from a to replicate the linked row in t and add the required c_id (and then table a to be dropped) so you get something like this;
| id | c_id | code | value |
|-------|-------|-------|-------|
...
| 25 | 1 | VI | 2.5 |
| 26 | 2 | VI | 2.5 |
| 27 | 3 | VI | 2.5 |
| 28 | 1 | BC | 2.5 |
| 29 | 4 | BC | 2.5 |
which will enable me to change the value column per c_id, rather than globally. The new rows can safely be added to the end of the table - or perhaps it would be better to have a new table with this information in.
Is there a query that can do this? I hope I don't have to do it by hand!
Assuming I'm understanding correctly, since you mentioned modifying tables, this is a one-time procedure.
You won't be able to add the rows to the end of either of the existing tables, since you have different column requirements. You'll have to either make a new table or modify the existing one. I chose the former, and then you can populate it using CREATE TABLE ... SELECT ... syntax:
CREATE TABLE new_t (id SERIAL, c_id INT, code VARCHAR(2), value FLOAT);
INSERT INTO new_t (c_id, code, value)
SELECT a.c_id, t.code, t.value FROM a INNER JOIN t ON (t.id = a.t_id);
http://sqlfiddle.com/#!9/c6765/2
I have a table that has the following properties.
| UPC | Cost | Items |
--------------------------
| abc | 2.50 | 30 |
| 123 | 2.11 | 40 |
Let's say I need to copy the information into another table, but I need to do each one as its own line item... for example, I need to end with...
| UPC | Cost | Sold | ID |
------------------------------
| abc | 2.50 | NULL | 1 |
| abc | 2.50 | NULL | 2 |
...
| abc | 2.50 | NULL | 29 |
| abc | 2.50 | NULL | 30 |
| 123 | 2.11 | NULL | 31 |
| 123 | 2.11 | NULL | 32 |
...
| 123 | 2.11 | NULL | 69 |
| 123 | 2.11 | NULL | 70 |
Is there a way to insert based off # of items in the original table?
I was thinking I could do something like this...
WHILE (SELECT Total FROM dbo.tempInventory) > 0
BEGIN
INSERT INTO dbo.Inventory (UPC, Cost, Sold)
SELECT (UPC, Cost, NULL)
FROM dbo.tempInventory
UPDATE dbo.tempInventory
SET Total = Total-1
END
And this would work for 1 UPC at a time. The issue is I'm working with over 3500 UPC's, and each have between 1 and 60 items to input.
I found a way to do it directly in SQL, but to be honest I'm not 100% sure HOW it works. Would anyone be able to explain?
WITH tally AS (
SELECT 1 n
UNION ALL
SELECT n + 1 FROM tally WHERE n < 100
)
SELECT UPC, n.n Position
FROM dbo.tempInventory t JOIN tally n
ON n.n <= t.Items
ORDER BY Description, Position
I am trying to run an MySQL query to copy over data from an old table (ps__product_review/rate) to a new table (ps_product_comment/grade) based on review ID (id_product_comment). But I am a bit lost on the SQL query, this is what I have but keep getting errors.
INSERT INTO ps_product_comment [(grade)]
SELECT rate
FROM ps__product_review
[WHERE ps__product_review.id_product_comment=ps_product_comment.id_product_comment];
Can anyone help write the correct query?
Edit:Essentially I am trying to populate the Grade column in the new table below.
Old table (ps__product_review)
+--------------------+----------+-----+
| id_product_comment | Comment | Rate|
+--------------------+----------+-----+
| 1 | Good | 2 |
| 2 | Great | 5 |
| 3 | OK | 3 |
| 4 | Brill | 4 |
| 5 | OK | 3 |
| 6 | Average | 2 |
| 7 | Bad | 1 |
+--------------------+----------+-----+
New Table (ps_product_comment)
+--------------------+----------+-------+
| id_product_comment | Comment | Grade |
+--------------------+----------+-------+
| 1 | Good | |
| 2 | Great | |
| 3 | OK | |
| 4 | Brill | |
| 5 | OK | |
| 6 | Average | |
| 7 | Bad | |
+--------------------+----------+-------+
If you want to update table with data from another table, use UPDATE with JOIN
UPDATE ps_product_comment
JOIN ps__product_review
ON ps__product_review.id_product_comment = ps_product_comment.id_product_comment
SET ps_product_comment.grade = ps__product_review.rate;
Remove the square brackets and I think you are missing the JOIN(since you are using that in your where clause):
INSERT INTO ps_product_comment (grade)
SELECT rate
FROM ps__product_review inner join ps_product_comment on
ps__product_review.id_product_comment=ps_product_comment.id_product_comment;
I am trying to insert data into a table in sorted order, for later fast retrieval. I am using an ordinal column to specify the order of the data. Like so:
SET #ctr = -1;
insert into search_data (trans_id, ordinal)
select trans_id, #ctr:=#ctr+1
from transactions
order by created;
created is a datetime field.
Doing the select without the insert has the rows coming back in the correct order, but the ctr variable does not increment correctly. E.g.:
+---+----------+--------------+---------------------+
| 1 | trans_id | #ctr:=#ctr+1 | created |
+---+----------+--------------+---------------------+
| 1 | 131379 | 232 | 2011-10-17 12:27:09 |
| 1 | 131377 | 231 | 2011-10-17 12:24:30 |
| 1 | 131311 | 230 | 2011-10-16 23:44:12 |
| 1 | 131305 | 229 | 2011-10-16 21:57:35 |
| 1 | 129948 | 46 | 2011-10-10 13:24:58 |
| 1 | 129947 | 45 | 2011-10-10 13:24:58 |
| 1 | 129946 | 44 | 2011-10-10 13:24:58 |
| 1 | 129945 | 43 | 2011-10-10 13:24:58 |
| 1 | 129944 | 42 | 2011-10-10 13:24:58 |
This technique has worked for me in MySQL 5.0, 4.x and 3.x. But it doesn't work in 5.1.
It seems like the sort is being done after the variable is incremented, whereas previously the variable was incremented after the sort
Any thoughts?
Try subquery it:
select trans_id, #ctr:=#ctr+1
from ( select trans_id
from transactions
order by created, trans_id ) as t
asdfasdf
There is an apostrophe mark at the end of the initialisation of the ctr variable. Please check if it conforms to the syntax. I think the compiler is getting confused by that apostrophe mark.