R sum column in second table based on if conditions - mysql

I am trying to sum the column in another table and put it in my current table based on a number of conditions.
table1 <- tribble(~company_id,~date,
1,"2018-01-02",
1,"2018-01-03",
2,"2018-01-02",
2,"2018-01-03")
table2 <- tribble(~other_id, company_id,~date_created,~max_rank,rank,date_closed,
1,1,"2018-01-02",20,2,NA,
1,1,"2018-01-03",22,1,NA,
2,2,"2018-01-02",20,5,NA,
2,2,"2018-01-03",22,4,NA)
I want to create a new column in table 1 that will imput the following formula:
= sum( (max_rank-rank)/(max_rank-1))
but only when:
(date<=date_created, date>(date_created+20), date<date_closed, max_rank-1!=0, rank!=0)
Edit
The output I hope to achieve should look like this:
Table 1
| company id | date | cc score |
---------------------------------------
| 1 | 2018-01-02 | 0.9473 |
| 1 | 2018-01-03 | 1.9473 |
| 2 | 2018-01-02 | 0.7895 |
| 2 | 2018-01-03 | 1.6466 |
The first can be calculated as (20-2)/(20-1) = 0.9473
The second is calculated as (20-2)/(20-1) + (22-1)/(22-1) = 1.9473

You can use dplyr package.
Please try the code below:
> library(dplyr)
> cbind(table1,table2)%>%inner_join(table1)%>%inner_join(table2)%>%filter(date<=date_created|date>(date_created+20)&max_rank-1!=0&rank!=0)%>%mutate(cc_data=(max_rank-rank)/(max_rank-1))%>%group_by(company_id)%>%mutate(cc_data=cumsum(cc_data))%>%select(company_id,date,cc_data)
Use of cbind() : We need both date_created and date column.
Two times inner_join(): To make sure there is no extra data.
Please suggest a better solution than this.

This seems to work:
table1[, cc_score := table2[table1,
on = .(company_id = company_id, date_created<=date, date_created_pls_20>date),
sum(ifelse(!is.na(rank) & (is.na(date_closed) | date_closed>date),
((max_rank-rank)/(max_rank-1)), 0)),
by = .EACHI][["V1"]]]
Where date_created_pls_20 is a column that takes the date_created column and simply adds 20

Related

find unique items based on date column

I need to find unique items based on date column. I tried to group the data together, but am not getting the desired result.
In the below sample i need to find the new entry i.e."New Company" seen on date 27th July because it does not exists on 16th July. I have thousand such rows and various dates.
The table contains issues seen on an Operating system datewise. I need to find the new issues a particular company is hitting. Pls help!
mysql> select * from testdata;
+------------+----------------+-----------------------+
| date | os_ver | account_name | count |
+------------+----------------+-----------------------+
| 2018-07-16 | 22.345-595 | Company AA1 | 2 |
| 2018-07-16 | 22.346-596 | Company BB1 | 1 |
| 2018-07-16 | 22.346-596 | Company CC1 | 2 |
| 2018-07-27 | 22.346-595 | Company AA1 | 1 |
| 2018-07-27 | 22.346-596 | Company BB1 | 2 |
| 2018-07-27 | 22.346-596 | New Company | 1 |
| 2018-07-27 | 22.346-596 | Company CC1 | 1 |
+------------+----------------+----------------------
I tried the below, but it's not showing the unique item:
SELECT * FROM `testdata` group by timestamp order by timestamp DESC
Your question isn't entirely clear. However if you are trying to find the earliest date for the first occurence of each account name, then see the following query.
SELECT t.*
FROM test t
LEFT JOIN test t1
ON t.date > t1.date
AND t.account_name = t1.account_name
WHERE t1.date IS NULL;
Here's an SQL Fiddle demonstrating the query with your sample data.
Alternatively, if you want to find all account names that occur only once, then see the following query.
SELECT t.*
FROM test t
GROUP BY t.account_name
HAVING COUNT(*) = 1;
Here's an SQL Fiddle demonstrating the query with your sample data.
your question is not much clear but i guess you need below something
select date,os_ver,account_name,count(*) from testdata
group by date,os_ver,account_name

MySQL - add text prefix before column name in SELECT statement

Here is my table:
| ID | NUMBER |
| 1 | 523 |
| 2 | 293 |
| 3 | 948 |
And now, I want to get all NUMBER values but I want to add in result two numbers - 48 - (without upadting existing results). So finally I want print these results:
| NUMBER |
| 48523 |
| 48293 |
| 48948 |
So I need a query, something like this:
SELECT '48' + `number` FROM `table`
but this query doesn't work fine (this query only update column name from NUMBER to 48 + NUMBER).
Any ideas?
Thanks.
You need CONCAT
SELECT CONCAT('48' , `number`) AS number FROM table
Demo

Cross table with multiselect

I have a table with 2 Columns, filled with strings
CREATE TABLE [tbl_text]
(
[directoryName] nvarchar(200),
[text1] nvarchar(200),
[text2] nvarchar(200)
)
The Strings are build like the following
| Text1 | Text2 |
|------------|----------|
|tz1 tz3 tz2 | al1 al2 |
| tz1 tz3 | al1 al3 |
| tz2 | al3 |
| tz3 tz2 | al1 al2 |
Now i want to Count how many times the TestN or TextN are resulting in the
| Text1 | al1 | al2 | al3 |
|-------|------|------|------|
| tz1 | 2 | 1 | 1 |
| tz2 | 2 | 2 | 1 |
| tz3 | 3 | 2 | 1 |
i tried solving it with an sql-query like this:
TRANSFORM Count(tt.directoryName) AS Value
SELECT tt.Text1
FROM tbl_text as tt
GROUP BY tt.Text1
PIVOT tt.Text2;
This works fine if i got fields only with one value like the third column (the complete datasource has to be like a one-value-style)
But in my case i'm using the strings for a multiselect...
If i try to conform this query onto a datasource filled with the " " between the values the result is complete messed up
Any suggestions how the query should look like to get this result ?
You'll have to split the strings inside Text1/Text2 before you can do anything with them. In VBA, you'd loop a recordset, use the Split() function and insert the results into a temp table.
In Sql Server there are more powerful options available.
Coming from here: Split function equivalent in T-SQL? ,
you should read this page:
http://www.sommarskog.se/arrays-in-sql-2005.html#tablelists

MySQL query - only exact result or every choice

I've a query that I need some help with -
As part of a form I've got a serial number field that is populated if there is a serial number, blank if it's not, or no result if it's an invalid serial number.
select *
from cust_site_contract as cs
where cs.serial_no = 'C20050' or (cs.serial_no <> 'C20050' and if(cs.serial_no = 'C20050',1,0)=0)
limit 10;
Here's a sample of the regular data:
+----------------------+-----------+-----------+-----------
| idcust_site_contract | system_id | serial_no | end_date
+----------------------+-----------+-----------+-----------
| 561315 | SH001626 | C19244 | 2009-12-21
| 561316 | SH001626 | C19244 | 2010-06-30
| 561317 | SH002125 | C19671 | 2010-05-31
| 561318 | SH001766 | C14781 | 2010-09-25
| 561319 | SH001766 | C14781 | 2011-02-15
| 561320 | SH002059 | C19020 | 2008-07-09
| 561321 | SH002639 | C18889 | 2008-03-31
| 561322 | SH002639 | C18889 | 2008-06-30
| 561323 | SH002715 | C20051 | 2010-04-30
| 561324 | SH002719 | C20057 | 2010-04-30
And an exact result would look something like this:
| 561487 | SH002837 | C20050 | 2012-07-04
I was writing this as a subquery so I could match the system_ids to customer and contract names, but realised I was getting garbage pretty early on.
I'm tempted to try and simplify it by saying the third case might not hold true (i.e. if it's an invalid serial number, allow the choice of any customer name and simply flag it in the data)
Has anyone got any ideas of where I'm going wrong? The combination of conditions is clearly wrong, and I can't work out how to make each side of the or statement mutually exclusive
Even if I try to evaluate only the if(sn = 'blah') I get the wrong result for obvious reasons, but can't think of a sane way to express it.
Many thanks
Scott
If there is is no contract with a serial number of C20050, this query will return all rows, otherwise, it will return only one row where serial_no is C20050:
SELECT a.*
FROM cust_site_contract a
INNER JOIN
(
SELECT COUNT(*) AS rowexists
FROM cust_site_contract
WHERE serial_no = 'C20050'
) b ON b.rowexists = 0
UNION ALL
(
SELECT *
FROM cust_site_contract
WHERE serial_no = 'C20050'
LIMIT 1
)
If you just write the query as below you will get blank if doesn't exists or it's an invalid serial number.
select cs.serial_no from cust_site_contract as cs where cs.serial_no = 'C20050'

MySQL data in column wise which is stored in row based

I am having a table with data stored in row basis as shown below.
UID | DetailsID | Data|
----------------------|
1 | 1 | A |
1 | 2 | 200|
1 | 3 | 2010-10-11 08:32 |
2 | 1 | B |
2 | 2 | 600|
2 | 3 | 2011-05-20 14:56 |
From this I need the output as follows
UID|1|2|3
------------
1|A|200|2010-10-11 08:32
2|B|600|2011-05-20 14:56
Here main thing is, the number of entries of DetailsID values is not known.
I wanted this one in MySQL.
Please help me out of this.
Not quite what you want, but other than loads of left joins i can only suggest:
SELECT UID,GROUP_CONCAT(DetailsID SEPARATOR ",") "DetailsIDs",GROUP_CONCAT(Data SEPARATOR ",") "Data" FROM data_table GROUP BY UID;
Do that transformation in your coding language, not in SQL.
you didnt say where you need the output. If you need the output in PHP pages it is simple only by creating the loop for the entries in columns wise.