Guest User

Untitled

a guest
Jan 21st, 2018
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.24 KB | None | 0 0
  1. /* Requirements:
  2.  
  3. I'm writing an SQL query for a search feature on a website in a PHP/MySQL application.
  4.  
  5. I have customer and ad tables. Customer may have many ads.
  6.  
  7. The user enters a keyword and sees the results in a web page. Here's the rules for the search results:
  8.  
  9. each item in the search result contains customer info and one ad for that customer
  10. the customer, or the customer's ad must match the keyword
  11. a customer may only appear once in the search results
  12. search results ordered by relevance (how many times the keyword is found in customer and ad fields)
  13. if the customer has more than one ad with equal relevance, then the ad with the greatest start date is chosen
  14.  
  15. The approach here is to break the problem down into smaller problems,
  16. solve the smaller problems, then work the solutions together to build
  17. the solution for the original problem.
  18.  
  19. */
  20.  
  21. USE mba;
  22. SET @keyword = LOWER('or');
  23. SET @like = CONCAT('%', @keyword, '%');
  24.  
  25. -- Q1: select active ads --
  26. SELECT ad.ad_id, ad.paid, ad.start_date, ad.end_date
  27. FROM ad
  28. WHERE ad.paid = 1
  29. AND ad.start_date <= NOW()
  30. AND ad.end_date >= NOW();
  31.  
  32. -- Q2: join customer and ad, selecting rows that match keyword in some way --
  33. SELECT customer.customer_id, ad.ad_id
  34. FROM customer
  35. JOIN state ON (customer.state_id = state.state_id)
  36. JOIN country ON (state.country_id = country.country_id)
  37. JOIN ad ON (customer.customer_id = ad.customer_id)
  38. WHERE (ad.description LIKE @like
  39. OR ad.text LIKE @like
  40. OR customer.title LIKE @like
  41. OR customer.company LIKE @like
  42. OR customer.city LIKE @like
  43. OR state.name LIKE @like
  44. OR customer.zip LIKE @like
  45. OR country.name LIKE @like
  46. OR customer.description LIKE @like
  47. OR CONCAT(customer.first_name, " ", customer.last_name) LIKE @like
  48. );
  49.  
  50. -- Q3: Q1 + Q2 --
  51. SELECT customer.customer_id, ad.ad_id
  52. FROM customer
  53. JOIN state ON (customer.state_id = state.state_id)
  54. JOIN country ON (state.country_id = country.country_id)
  55. JOIN ad ON (customer.customer_id = ad.customer_id)
  56. WHERE (
  57. ad.description LIKE @like
  58. OR ad.text LIKE @like
  59. OR customer.title LIKE @like
  60. OR customer.company LIKE @like
  61. OR customer.city LIKE @like
  62. OR state.name LIKE @like
  63. OR customer.zip LIKE @like
  64. OR country.name LIKE @like
  65. OR customer.description LIKE @like
  66. OR CONCAT(customer.first_name, " ", customer.last_name) LIKE @like
  67. )
  68. AND ad.ad_id IN (
  69. SELECT ad.ad_id
  70. FROM ad
  71. WHERE ad.paid = 1
  72. AND ad.start_date <= NOW()
  73. AND ad.end_date >= NOW()
  74. );
  75.  
  76. -- Q4: count customers --
  77. SELECT COUNT(customer.customer_id) AS customers
  78. FROM customer;
  79.  
  80. -- Q5: count customers with ads --
  81. SELECT COUNT(DISTINCT ad.customer_id) AS customers_with_ads
  82. FROM ad;
  83.  
  84. -- Q6: show start dates for all ads --
  85. SELECT ad.customer_id, ad.ad_id, ad.start_date
  86. FROM ad
  87. ORDER BY ad.customer_id, ad.start_date DESC;
  88.  
  89. -- Q7: select max ad start date for each customer --
  90. SELECT ad.customer_id, MAX(ad.start_date) AS start_date
  91. FROM ad
  92. GROUP BY ad.customer_id
  93. ORDER BY ad.customer_id, ad.start_date DESC;
  94.  
  95. -- Q8: get latest ad for each customer --
  96. SELECT ad.customer_id, ad.ad_id, ad.start_date
  97. FROM ad
  98. JOIN (
  99. SELECT ad.customer_id, MAX(ad.start_date) AS start_date
  100. FROM ad
  101. GROUP BY ad.customer_id
  102. ) AS max USING (customer_id, start_date);
  103.  
  104. -- Q9: calculate relevance for active active ads --
  105. SELECT
  106. ad.ad_id,
  107. customer.customer_id,
  108. (
  109. ((LENGTH(ad.description) - LENGTH(REPLACE(LOWER(ad.description), @keyword, ''))) / LENGTH(@keyword))
  110. + ((LENGTH(ad.text) - LENGTH(REPLACE(LOWER(ad.text), @keyword, ''))) / LENGTH(@keyword))
  111. + ((LENGTH(customer.title) - LENGTH(REPLACE(LOWER(customer.title), @keyword, ''))) / LENGTH(@keyword))
  112. + ((LENGTH(customer.company) - LENGTH(REPLACE(LOWER(customer.company), @keyword, ''))) / LENGTH(@keyword))
  113. + ((LENGTH(customer.city) - LENGTH(REPLACE(LOWER(customer.city), @keyword, ''))) / LENGTH(@keyword))
  114. + ((LENGTH(state.name) - LENGTH(REPLACE(LOWER(state.name), @keyword, ''))) / LENGTH(@keyword))
  115. + ((LENGTH(customer.zip) - LENGTH(REPLACE(LOWER(customer.zip), @keyword, ''))) / LENGTH(@keyword))
  116. + ((LENGTH(country.name) - LENGTH(REPLACE(LOWER(country.name), @keyword, ''))) / LENGTH(@keyword))
  117. + ((LENGTH(customer.description) - LENGTH(REPLACE(LOWER(customer.description), @keyword, ''))) / LENGTH(@keyword))
  118. + ((LENGTH(customer.first_name) - LENGTH(REPLACE(LOWER(customer.first_name), @keyword, ''))) / LENGTH(@keyword))
  119. + ((LENGTH(customer.last_name) - LENGTH(REPLACE(LOWER(customer.last_name), @keyword, ''))) / LENGTH(@keyword))
  120. ) AS relevance,
  121. ad.start_date
  122. FROM customer
  123. JOIN state USING (state_id)
  124. JOIN country USING (country_id)
  125. JOIN ad USING (customer_id)
  126. WHERE ad.ad_id IN (
  127. SELECT ad.ad_id
  128. FROM ad
  129. WHERE ad.paid = 1
  130. AND ad.start_date <= NOW()
  131. AND ad.end_date >= NOW()
  132. )
  133. ORDER BY customer.customer_id, relevance DESC, ad.start_date DESC;
  134.  
  135. -- Q10: get the most recent of the most relevant ads for each customer --
  136. SELECT
  137. customer.customer_id,
  138. customer.first_name,
  139. customer.middle_initial,
  140. customer.last_name,
  141. customer.title,
  142. customer.email,
  143. customer.mobile_phone,
  144. customer.office_phone,
  145. customer.tf_phone,
  146. customer.fax,
  147. customer.personal_url,
  148. customer.company,
  149. customer.description,
  150. customer.website,
  151. customer.street,
  152. customer.city,
  153. state.name AS state,
  154. customer.zip,
  155. country.name AS country,
  156. ad.ad_id,
  157. ad.ad_type_id,
  158. ad.url,
  159. ad.text,
  160. ad.description AS ad_description,
  161. ad.file_url
  162. FROM customer
  163. JOIN state USING (state_id)
  164. JOIN country USING (country_id)
  165. JOIN ad USING (customer_id)
  166. JOIN (
  167. SELECT ad.customer_id, MAX(r.relevance) AS relevance
  168. FROM ad
  169. JOIN (
  170. SELECT
  171. ad.ad_id,
  172. (
  173. ((LENGTH(ad.description) - LENGTH(REPLACE(LOWER(ad.description), @keyword, ''))) / LENGTH(@keyword))
  174. + ((LENGTH(ad.text) - LENGTH(REPLACE(LOWER(ad.text), @keyword, ''))) / LENGTH(@keyword))
  175. + ((LENGTH(customer.title) - LENGTH(REPLACE(LOWER(customer.title), @keyword, ''))) / LENGTH(@keyword))
  176. + ((LENGTH(customer.company) - LENGTH(REPLACE(LOWER(customer.company), @keyword, ''))) / LENGTH(@keyword))
  177. + ((LENGTH(customer.city) - LENGTH(REPLACE(LOWER(customer.city), @keyword, ''))) / LENGTH(@keyword))
  178. + ((LENGTH(state.name) - LENGTH(REPLACE(LOWER(state.name), @keyword, ''))) / LENGTH(@keyword))
  179. + ((LENGTH(customer.zip) - LENGTH(REPLACE(LOWER(customer.zip), @keyword, ''))) / LENGTH(@keyword))
  180. + ((LENGTH(country.name) - LENGTH(REPLACE(LOWER(country.name), @keyword, ''))) / LENGTH(@keyword))
  181. + ((LENGTH(customer.description) - LENGTH(REPLACE(LOWER(customer.description), @keyword, ''))) / LENGTH(@keyword))
  182. + ((LENGTH(customer.first_name) - LENGTH(REPLACE(LOWER(customer.first_name), @keyword, ''))) / LENGTH(@keyword))
  183. + ((LENGTH(customer.last_name) - LENGTH(REPLACE(LOWER(customer.last_name), @keyword, ''))) / LENGTH(@keyword))
  184. ) AS relevance
  185. FROM customer
  186. JOIN state USING (state_id)
  187. JOIN country USING (country_id)
  188. JOIN ad USING (customer_id)
  189. WHERE ad.ad_id IN (
  190. SELECT ad.ad_id
  191. FROM ad
  192. WHERE ad.paid = 1
  193. AND ad.start_date <= NOW()
  194. AND ad.end_date >= NOW()
  195. )
  196. ) r USING (ad_id)
  197. GROUP BY ad.customer_id
  198. ) AS relevance USING (customer_id)
  199. JOIN (
  200. SELECT ad.customer_id, MAX(ad.start_date) AS start_date
  201. FROM ad
  202. GROUP BY ad.customer_id
  203. ) AS latest USING (customer_id, start_date)
  204. ORDER BY relevance DESC, ad.start_date;
Add Comment
Please, Sign In to add comment