{"id":346,"date":"2018-08-30T12:47:36","date_gmt":"2018-08-30T12:47:36","guid":{"rendered":"https:\/\/sidroniolima.com.br\/blog\/?p=346"},"modified":"2018-08-30T12:48:17","modified_gmt":"2018-08-30T12:48:17","slug":"cross-apply-no-sql-server","status":"publish","type":"post","link":"https:\/\/sidroniolima.com.br\/blog\/2018\/08\/30\/cross-apply-no-sql-server\/","title":{"rendered":"Cross Apply no Sql Server"},"content":{"rendered":"\n<div class=\"twitter-share\"><a href=\"https:\/\/twitter.com\/intent\/tweet?hashtags=sqlserver%20%23query%20%23ti%20%23it&#038;via=sidroniolima\" class=\"twitter-share-button\">Tweet<\/a><\/div>\n<p><a href=\"https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2018\/08\/sql.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-351\" src=\"https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2018\/08\/sql.png\" alt=\"\" width=\"209\" height=\"110\" srcset=\"https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2018\/08\/sql.png 600w, https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2018\/08\/sql-300x158.png 300w\" sizes=\"auto, (max-width: 209px) 100vw, 209px\" \/><\/a><\/p>\n<p>Precisava criar um relat\u00f3rio que listasse a m\u00e9dia das 3 primeiras vendas de clientes novos do ano atual (2018).<\/p>\n<p>A query ent\u00e3o deve conter 2 tabelas: cliente e pedidos. O filtro do cliente e dos pedidos \u00e9 b\u00e1sico. O dif\u00edcil \u00e9 fazer com que os pedidos recebam o c\u00f3digo do cliente do Select e aplic\u00e1-lo na query que traz os pedidos.<\/p>\n<p>A princ\u00edpio tentei fazer um Join, depois uma subquery mas por conta da operador TOP n\u00e3o conseguia. Logicamente o TOP 3 retornaria apenas tr\u00eas registros da tabela pedido e n\u00e3o tr\u00eas pedidos da tabela pedido para cada cliente da query principal.<\/p>\n<p>Pesquisando um pouco eu cheguei a uma query com dois joins que n\u00e3o deu muito certo, mas a l\u00f3gica at\u00e9 que \u00e9 boa:<\/p>\n<p><span style=\"font-size: 6pt; font-family: arial, helvetica, sans-serif;\"><code>SELECT<\/code><\/span><br \/>\n<span style=\"font-size: 6pt; font-family: arial, helvetica, sans-serif;\"><code>A1_COD,<\/code><\/span><br \/>\n<span style=\"font-size: 6pt; font-family: arial, helvetica, sans-serif;\"><code>Z7.Z7_CONSULT,<\/code><\/span><br \/>\n<span style=\"font-size: 6pt; font-family: arial, helvetica, sans-serif;\"><code>Z7.Z7_NUM,<\/code><\/span><br \/>\n<span style=\"font-size: 6pt; font-family: arial, helvetica, sans-serif;\"><code>Z7.Z7_DTFECHA,<\/code><\/span><br \/>\n<span style=\"font-size: 6pt; font-family: arial, helvetica, sans-serif;\"><code>B.*<\/code><\/span><br \/>\n<span style=\"font-size: 6pt; font-family: arial, helvetica, sans-serif;\"><code>FROM<\/code><\/span><br \/>\n<span style=\"font-size: 6pt; font-family: arial, helvetica, sans-serif;\"><code>SA1010 A1<\/code><\/span><br \/>\n<span style=\"font-size: 6pt; font-family: arial, helvetica, sans-serif;\"><code>LEFT JOIN (SELECT TOP 3 Z7_NUM, Z7_CONSULT FROM SZ7010 WHERE D_E_L_E_T_ = '' AND Z7_STATUS = 'F' ORDER BY Z7_DTFECHA) B ON A1.A1_COD = B.Z7_CONSULT<\/code><\/span><br \/>\n<span style=\"font-size: 6pt; font-family: arial, helvetica, sans-serif;\"><code>LEFT JOIN SZ7010 Z7 ON Z7.Z7_NUM = B.Z7_NUM<\/code><\/span><br \/>\n<span style=\"font-size: 6pt; font-family: arial, helvetica, sans-serif;\"><code>WHERE<\/code><\/span><br \/>\n<span style=\"font-size: 6pt; font-family: arial, helvetica, sans-serif;\"><code>A1.D_E_L_E_T_ = '' AND<\/code><\/span><br \/>\n<span style=\"font-size: 6pt; font-family: arial, helvetica, sans-serif;\"><code>A1.A1_DTCAD &gt; 20180101 AND<\/code><\/span><br \/>\n<span style=\"font-size: 6pt; font-family: arial, helvetica, sans-serif;\"><code>A1.A1_STATUS = 1<\/code><\/span><br \/>\n<span style=\"font-size: 6pt; font-family: arial, helvetica, sans-serif;\"><code>ORDER BY<\/code><\/span><br \/>\n<span style=\"font-size: 6pt; font-family: arial, helvetica, sans-serif;\"><code>A1.A1_COD<\/code><\/span><\/p>\n<p>Por\u00e9m n\u00e3o funcionou. : (<\/p>\n<p>A solu\u00e7\u00e3o foi a utilizar o operador CROSS APPLY, que utiliza uma query como entrada para outra e as uni. Analisando o problema das novatas em quest\u00e3o fica f\u00e1cil entender o funcionamento. Veja a query:<\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif; font-size: 6pt;\"><code>SELECT<br \/>\nA1_COD,<br \/>\nA1_NOME,<br \/>\nA1_DTCAD,<br \/>\nCA.*<br \/>\nFROM<br \/>\nSA1010 A1<br \/>\nCROSS APPLY (<br \/>\nSELECT TOP 3<br \/>\nZ7_NUM,<br \/>\nZ7_CONSULT,<br \/>\nZ7_QTDCOMD,<br \/>\nZ7_REGIAO,<br \/>\nZ7_DTFECHA<br \/>\nFROM<br \/>\nSZ7010 B<br \/>\nWHERE<br \/>\nB.D_E_L_E_T_ = ''\t\tAND<br \/>\nB.Z7_STATUS = 'F'\t\tAND<br \/>\nB.Z7_SERIE\t&lt;&gt; 'DIR'\tAND<br \/>\nA1.A1_COD = B.Z7_CONSULT<br \/>\nORDER BY<br \/>\nZ7_DTFECHA) CA<br \/>\nWHERE<br \/>\nA1.D_E_L_E_T_ = ''\t\tAND<br \/>\nA1.A1_DTCAD &gt; 20180101\t\tAND<br \/>\nA1.A1_STATUS = 1<br \/>\nORDER BY<br \/>\nA1.A1_COD<\/code><\/span><\/p>\n<p>A query ent\u00e3o traz os 3 primeiros pedidos para cada cliente retornado na query inicial e junta os resultados.<\/p>\n<p><span style=\"font-size: 8pt;\"><em>109244 &lt;&lt;NOME&gt;&gt; 20180102 842355 109244 23 000122 20180203<\/em><\/span><br \/>\n<span style=\"font-size: 8pt;\"><em>109244 &lt;&lt;NOME&gt;&gt; 20180102 844817 109244 45 000122 20180312<\/em><\/span><br \/>\n<span style=\"font-size: 8pt;\"><em>109244 &lt;&lt;NOME&gt;&gt; 20180102 862112 109244 54 000122 20180419<\/em><\/span><br \/>\n<span style=\"font-size: 8pt;\"><em>109255 &lt;&lt;NOME&gt;&gt; 20180102 839520 109255 17 000072 20180204<\/em><\/span><br \/>\n<span style=\"font-size: 8pt;\"><em>109255 &lt;&lt;NOME&gt;&gt; 20180102 854113 109255 28 000072 20180313<\/em><\/span><br \/>\n<span style=\"font-size: 8pt;\"><em>109255 &lt;&lt;NOME&gt;&gt; 20180102 861392 109255 42 000072 20180417<\/em><\/span><br \/>\n<span style=\"font-size: 8pt;\"><em>109260 &lt;&lt;NOME&gt;&gt; 20180105 838082 109260 25 000093 20180205<\/em><\/span><br \/>\n<span style=\"font-size: 8pt;\"><em>109260 &lt;&lt;NOME&gt;&gt; 20180105 851091 109260 41 000093 20180314<\/em><\/span><br \/>\n<span style=\"font-size: 8pt;\"><em>109260 &lt;&lt;NOME&gt;&gt; 20180105 863113 109260 41 000093 20180418<\/em><\/span><\/p>\n<p>Depois disso apenas alterei a query para que ao inv\u00e9s dos tr\u00eas pedidos retornasse a m\u00e9dia de pe\u00e7as vendidas e pronto. Relat\u00f3rio concluido com performance e acuracidade.<\/p>\n<p>Seguem dois links que tratam do operador Cross Apply que me ajudaram:<\/p>\n<p><span style=\"font-size: 8pt;\"><a href=\"https:\/\/www.tutorialti.com\/2015\/02\/o-que-e-cross-apply-sql-server.htm\">https:\/\/www.tutorialti.com\/2015\/02\/o-que-e-cross-apply-sql-server.htm<\/a>l<\/span><\/p>\n<p><span style=\"font-size: 8pt;\"><a href=\"http:\/\/blog.dbaacademy.com.br\/sql-server-cross-apply-e-cross-join\/\">http:\/\/blog.dbaacademy.com.br\/sql-server-cross-apply-e-cross-join\/<\/a><\/span><\/p>\n<p>Espero ter ajudado e at\u00e9!<\/p>\n\n<div class=\"twitter-share\"><a href=\"https:\/\/twitter.com\/intent\/tweet?hashtags=sqlserver%20%23query%20%23ti%20%23it&#038;via=sidroniolima\" class=\"twitter-share-button\">Tweet<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Precisava criar um relat\u00f3rio que listasse a m\u00e9dia das 3 primeiras vendas de clientes novos do ano atual (2018). A query ent\u00e3o deve conter 2 tabelas: cliente e pedidos. O filtro do cliente e dos pedidos \u00e9 b\u00e1sico. O dif\u00edcil \u00e9 fazer com que os pedidos recebam o c\u00f3digo do cliente do Select e aplic\u00e1-lo [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[83],"tags":[85,86,84],"class_list":["post-346","post","type-post","status-publish","format-standard","hentry","category-sql","tag-crossapply","tag-query","tag-sqlserver"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/posts\/346","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/comments?post=346"}],"version-history":[{"count":4,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/posts\/346\/revisions"}],"predecessor-version":[{"id":352,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/posts\/346\/revisions\/352"}],"wp:attachment":[{"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/media?parent=346"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/categories?post=346"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/tags?post=346"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}