GET

GET 메서드는 특정한 리소스를 가져오도록 요청한다. GET 요청은 데이터를 가져올 때만 사용해야 한다.

 

 

POST

POST 메서드는 서버로 데이터를 전송하여 리소스를 추가하거나 생성하기 위해 사용하는 메서드이다. GET 메서드와 반대로 요청 Header의 Content-Type에 컨텐츠 타입을 명시하며, HTTP 패킷의 Body에는 데이터를 담아 서버로 전송한다. 

 

 

PUT

PUT 메서드는 요청 페이로드를 사용해 새로운 리소스를 생성하거나, 대상 리소스를 나타내는 데이터를 대체한다. 즉 PUT 메소드는 문서 전체의 완전한 교체만을 허용한다. PUT과 POST의 차이는 멱등성으로, PUT 메서드는 멱등성을 가진다. 이는 한 번을 보내도, 여러 번을 연속으로 보내도 같은 효과를 보인다는 뜻이다.

 

 

PATCH

PATCH 메소드는 리소스의 부분적인 수정을 할 때 사용된다. PATCH 메서드는 멱등성을 가지지 않는데, 이는 동일한 patch 요청이 다른 결과를 야기할 수도 있음을 뜻한다. 하지만 PATCH를 PUT과 같은 방식으로 사용함으로써 멱등성을 가지게 할 수도 있다.

 

 

* 멱등성이란, 수학에서 사용하는 용어에서 유래한 것으로. 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질을 뜻한다. 동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 같은 효과를 지니고, 서버의 상태도 동일하게 남을 때, 해당 HTTP 메서드가 멱등성을 가졌다고 한다. 다른 말로는, 멱등성 메서드에는 통계 기록 등을 제외하면 어떠한 부수 효과(side effect)도 존재해서는 안된다는 뜻이다.

GETHEADPUTDELETE 메서드는 멱등성을 가지며, POST 메서드는 그렇지 않다.

 

 

 

 

'TIL > WEEK1' 카테고리의 다른 글

WEEK 1. 드디어 첫 프로젝트 끝!  (0) 2023.05.19
WEEK1. PUT방식으로 수정기능 구현  (0) 2023.05.17
WEEK1. REST API  (0) 2023.05.16
WEEK1. Git  (0) 2023.05.15

팀프로젝트 진행사항

    <script>
        function update_profile() {
            let name = $('#name').val()
            let blog = $('#blog').val()
            let mbti = $('#mbti').val()
            let desc = $('#desc').val()
            let img = $('#img').val()
            let merit = $('#merit').val()

            var data = {
                "name": name,
                "blog":blog,
                "mbti":mbti,
                "desc":desc,
                "img":img,
                "merit":merit
            }
            
            var jsonData = JSON.stringify(data);

            fetch("/update/{{ member_id['_id'] }}", {
                method:'PUT',
                headers:{'content-type':'application/json'},
                body:jsonData
            }).then((res) => res.json()).then((data) => {
                alert(data['msg'])
                location.reload()
            })
            
        }
    </script>
    
    <body>
    <div class="container">
        <div class>
            <div class="input-group mb-3">
                <label class="input-group-text" for="size">사진</label>
                <input id="img" type="url" class="form-control" />
            </div>
            <div class="input-group mb-3">
                <span class="input-group-text">이름</span>
                <input id="name" value="{{ member['name']}}" class="form-control" />
            </div>
            <div class="input-group mb-3">
                <span class="input-group-text">블로그 주소</span>
                <input id="blog" value="{{ member['blog']}}" class="form-control" />
            </div>
            <div class="input-group mb-3">
                <label class="input-group-text" for="size">MBTI</label>
                <input id="mbti" value="{{ member['mbti']}}" type="text" class="form-control" />
            </div>
            <div class="input-group mb-3">
                <label class="input-group-text" for="size">장점</label>
                <input id="merit" value="{{ member['merit']}}" type="text" class="form-control" />
            </div>
            <div class="input-group mb-3">
                <label class="input-group-text" for="size">자기소개</label>
                <input id="desc" value="{{ member['desc']}}" type="text" class="form-control" />
            </div>
        </div>
        <div class="d-flex justify-content-around">
            <button type="button" onClick="update_profile()" class="btn btn-light">수정</button>
            <a href="/view/{{ member_id['_id'] }}"><button class="btn btn-light">취소</button></a>
        </div>
    </div>

</body>
@app.route("/update/<id>", methods=["PUT"])
def update_post(id):
    receive = request.get_json()
    name_receive = receive['name']
    blog_receive = receive['blog']
    mbti_receive = receive['mbti']
    img_receive = receive['img']
    desc_receive = receive['desc']
    merit_receive = receive['merit']
    
    doc = {
        'name':name_receive,
        'blog':blog_receive,
        'mbti':mbti_receive,
        'img':img_receive,
        'merit':merit_receive,
        'desc':desc_receive
    }

    db.members.update_one({'_id': ObjectId(id)},{'$set':doc})
    return jsonify({'msg':'수정완료!'})

어제 FormData로 시도했다가 실패해서 데이터를 JSON으로 변환해서 시도해봤더니 잘 작동했다.

 

  • JSON.stringify(): JavaScript 객체를 JSON 문자열로 변환해준다.
  • request.get_json() : JSON 형식으로 전달된 요청 본문은 flask에서 request.get_json() 함수로 받을 수 있다.

 

 

 

 

 

'TIL > WEEK1' 카테고리의 다른 글

WEEK 1. 드디어 첫 프로젝트 끝!  (0) 2023.05.19
WEEK1. POST와 PUT의 차이점  (0) 2023.05.18
WEEK1. REST API  (0) 2023.05.16
WEEK1. Git  (0) 2023.05.15

1. 리소스

리소스는 URI로 식별한다.

Collection : 복수의 element

Element : 하나하나의 데이터

 

2. REST 

Representational State Transfer

  • 자원(Resource): URI
  • 행위(Verb): HTTP Method
  • 표현(Representations)

 

3. HTTP Method

REST를 지키면서 행위를 전달하는 방법

 

patch는 부분 수정이 가능하지만 put은 전체 데이터를 입력받아 덮어쓰므로  전송하지 않은 데이터는 삭제한다.


팀프로젝트 진행사항

프로필 수정기능을 구현해봤다.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
        crossorigin="anonymous"></script>
    <title>수정하기</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script>
    </script>
    <style>
        .container {
            justify-content: center;
            margin: auto;
            width: 50%;
            padding: 4rem;
        }
    </style>
</head>

<body>
    <div class="container">
        <form action="/update/{{ member['_id'] }}" method="post">
            <div class>
                <div class="input-group mb-3">
                    <label class="input-group-text" for="size">사진</label>
                    <input name="img_give" type="url" class="form-control" />
                </div>
                <div class="input-group mb-3">
                    <span class="input-group-text">이름</span>
                    <input name="name_give" value="{{ member['name']}}" class="form-control" />
                </div>
                <div class="input-group mb-3">
                    <span class="input-group-text">블로그 주소</span>
                    <input name="blog_give" value="{{ member['blog']}}" class="form-control" />
                </div>
                <div class="input-group mb-3">
                    <label class="input-group-text" for="size">MBTI</label>
                    <input name="mbti_give" value="{{ member['mbti']}}" type="text" class="form-control" />
                </div>
                <div class="input-group mb-3">
                    <label class="input-group-text" for="size">장점</label>
                    <input name="merit_give" value="{{ member['merit']}}" type="text" class="form-control" />
                </div>
                <div class="input-group mb-3">
                    <label class="input-group-text" for="size">자기소개</label>
                    <input name="desc_give" value="{{ member['desc']}}" type="text" class="form-control" />
                </div>
            </div>
            <div class="d-flex justify-content-around">
                <button type="submit" class="btn btn-light">수정</button>
                <a href="/view/{{ member_id['_id'] }}"><button class="btn btn-light">취소</button></a>
            </div>

        </form>
    </div>

</body>

</html>
#수정
@app.route("/update/<id>", methods=["GET"])
def update_get(id):
    find_member = db.members.find_one({"_id": ObjectId(id)})
    find_member['_id'] = str(find_member['_id'])
    find_id = db.members.find_one({'_id' : ObjectId(id)},{'id':True})
    return render_template('update.html', member=find_member, member_id=find_id)

@app.route("/update/<id>", methods=["POST"])
def update_post(id):
    name_receive = request.form['name_give']
    blog_receive = request.form['blog_give']
    mbti_receive = request.form['mbti_give']
    img_receive = request.form['img_give']
    desc_receive = request.form['desc_give']
    merit_receive = request.form['merit_give']

    find_member = db.members.find_one({"_id": ObjectId(id)})
    find_member['_id'] = str(find_member['_id'])

    db.members.update_one({'_id': ObjectId(id)},{'$set':{'name':name_receive}})
    db.members.update_one({'_id': ObjectId(id)},{'$set':{'blog':blog_receive}})
    db.members.update_one({'_id': ObjectId(id)},{'$set':{'mbti':mbti_receive}})
    db.members.update_one({'_id': ObjectId(id)},{'$set':{'img':img_receive}})
    db.members.update_one({'_id': ObjectId(id)},{'$set':{'desc':desc_receive}})
    db.members.update_one({'_id': ObjectId(id)},{'$set':{'merit':merit_receive}})

    return redirect('/view/'+id)

put 방식을 이용해 업데이트 기능을 구현해보고 싶었는데 form에서는 put을 지원하지 않아 post방식으로 구현했다. 다른 방법을 생각해봐야 될 것 같다.

'TIL > WEEK1' 카테고리의 다른 글

WEEK 1. 드디어 첫 프로젝트 끝!  (0) 2023.05.19
WEEK1. POST와 PUT의 차이점  (0) 2023.05.18
WEEK1. PUT방식으로 수정기능 구현  (0) 2023.05.17
WEEK1. Git  (0) 2023.05.15

1. CLI 명령어

pwd 현재 경로 확인
ls
ls -al
현재 경로의 파일 및 폴더 조회
숨김 파일 및 폴더까지 조회
cd
cd ..
cd ~

디렉토리 이동

상위 디렉토리로 이동
홈 디렉토리로 이동

touch 비어있는 파일 생성
cat 파일 내용 확인
vi
a 또는 i
ESC
:w
:q
(:wq로 한번에 써도 됨)
파일 편집
입력모드
빠져나가기
저장
닫기
rm
rm -rf
비어있는 디렉토리 및 파일 삭제
비어있지 않은 디렉토리 삭제
mkdir 디렉토리 생성

 

2. commit

유의미한 변화가 결과물로 나온 것

ex) 새 기능 추가, 버그 삭제, 버그 수정

 

3.  깃이 관리하는 세개의 공간

  • 작업 디렉토리 : 버전 관리 대상이 위치하는 공간 ( .git이 있는 디렉토리)
  • 스테이지 : 다음 버전이 될 후보가 올라가는 공간
  • 저장소 : 버전이 만들어지고 관리되는 공간

 

4. 브랜치

브랜치로 문제 해결하기

브랜치로 문제 해결하기

빨리감기 병합 : 기존의 branch에서 수정/추가 사항이 추가된 branch를 병합하는 과정

빨리감기 병합

 

5. HEAD

현재 작업중인 브랜치의 커밋을 가리킨다.

일반적으로 현재 작업 중인 브랜치의 최신 커밋을 가리킨다.

한 마디로 '내가 지금 어디에서 작업중인가'를 가리킨다.

 

6. git 명령어

[기본]

git init
  - 현재 디렉토리를 git local repository[Working Directory]로 지정(생성)
  - ls -al 명령어로 .git 숨김파일 생성 확인
  - rm -rf .git 명령어로 local repository 삭제
git status
  - 파일 상태 확인(staged, untracked, ..)
git add 파일명
  - 해당 파일을 [Staging Area]로 이동(tracking)
git add .
  -현재 폴더의 전체 파일을 이동
git commit
  - [Staging Area]에 있는 파일을 원격저장소[Repository]로 커밋
  - 옵션없이 해당 명령어만 입력할 경우 editor 호출
git commit -m "커밋메세지"
  - editor 호출없이 바로 커밋
git commit -am "커밋메세지"
  - [Staging Area]에 올림과 동시에 커밋(= git add .+ git commit -m "커밋메세지")

  - 단, 1번이라도 커밋된 대상만 사용 가능
git diff
  - local repository[Working Directory]와 [Staging Area]의 차이를 보여줌
git log
  - commit 로그 확인

 

[브랜치]

git branch
  - 브랜치 목록 조회(현재 속한 브랜치는 앞에 *가 붙음)
git branch 브랜치명
  - 브랜치명으로 브랜치 생성
  - 단, main 브랜치에 1번 이상 commit 해야함
git branch checkout 브랜치명
  - 해당 브랜치로 local repository[Working Directory] 변경
git branch -b 브랜치명
  - 브랜치 생성 후 checkout(= git branch 브랜치명 + git branch checkout 브랜치명)
git branch -d 브랜치명
  - 브랜치명 브랜치 삭제
git branch merge 브랜치명

 

'TIL > WEEK1' 카테고리의 다른 글

WEEK 1. 드디어 첫 프로젝트 끝!  (0) 2023.05.19
WEEK1. POST와 PUT의 차이점  (0) 2023.05.18
WEEK1. PUT방식으로 수정기능 구현  (0) 2023.05.17
WEEK1. REST API  (0) 2023.05.16
  • GET 방식

GET은 서버로부터 정보를 조회하기 위해 설계된 메소드로 주로 데이터를 읽거나(Read), 검색(Retrieve)할 때에 사용된다.
GET은 요청을 전송할 때 필요한 데이터를 Body에 담지 않고, 쿼리스트링을 통해 전송한다. 쿼리스트링이란 URL의 끝에 ?와 함께 이름과 값으로 쌍을 이루는 요청 파라미터로 요청 파라미터가 여러 개이면 &로 연결한다. 

 

예) www.example-url.com/resources?name1=value1&name2=value2

여기서 요청 파라미터명은 name1, name2이고, 각각의 파라미터는 value1, value2라는 값으로 서버에 요청을 보내게 된다.

 

 

 

  • POST 방식

POST는 리소스를 생성/변경하기 위해 설계되었기 때문에 GET과 달리 전송해야될 데이터를 HTTP 메세지의 Body에 담아서 전송한다. HTTP 메세지의 Body는 길이의 제한없이 데이터를 전송할 수 있으므로 POST 요청은 GET과 달리 대용량 데이터를 전송할 수 있다. 이처럼 POST는 데이터가 Body로 전송되고 내용이 눈에 보이지 않아 GET보다 보안적인 면에서 안전하다고 생각할 수 있지만, POST 요청도 크롬 개발자 도구, Fiddler와 같은 툴로 요청 내용을 확인할 수 있기 때문에 민감한 데이터의 경우에는 반드시 암호화해 전송해야 한다.

그리고 POST로 요청을 보낼 때는 요청 헤더의 Content-Type에 요청 데이터의 타입을 표시해야 된다. 데이터 타입을 표시하지 않으면 서버는 내용이나 URL에 포함된 리소스의 확장자명 등으로 데이터 타입을 유추한다. 만약, 알 수 없는 경우에는 application/octet-stream로 요청을 처리한다.

참고) POST는 생성, 수정, 삭제에 사용할 수 있지만, 생성에는 POST, 수정은 PUT 또는 PATCH, 삭제는 DELETE가 더 용도에 맞는 메소드이다.

 

 

<!DOCTYPE html>
<html>

<head>
  <title>상세 페이지</title>
  <script>

  </script>
</head>

<body>
  <div class="container" id="card-box">
    <h1>제목 : {{ movie['title'] }}</h1>
    <img src="{{ movie['image'] }}" alt="image" style="max-width: 200px; height: auto;">
    <p>내용 : {{ movie['desc'] }}</p>
    <p>평점 :
      {% for i in range(movie['star']|int) %}
      ⭐
      {% endfor %}
    </p>
    <p>리뷰 : {{ movie['comment'] }}</p>
  </div>

  <a href="/update/{{ find_id['_id'] }}">수정</a>
  <button onclick="location.href='/'">목록</button>
  <form action="/delete/{{ find_id['_id'] }}" method="POST"><input type="submit" value="삭제"></form>
</body>

</html>
from flask import Flask, render_template, request, jsonify, redirect
app = Flask(__name__)

from bson.objectid import ObjectId

from pymongo import MongoClient
client = MongoClient('mongodb+srv://sparta:test@cluster0.awfowzp.mongodb.net/?retryWrites=true&w=majority')
db = client.dbsparta

import requests
from bs4 import BeautifulSoup

@app.route('/')
def home():
    return render_template('index.html')

@app.route("/movies/new", methods=["GET"])
def get_write():

   return render_template('write.html')

@app.route("/movies/new", methods=["POST"])
def post_write():
    url_receive = request.form['url_give']
    comment_receive = request.form['comment_give']
    star_receive = request.form['star_give']

    
    headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
    data = requests.get(url_receive,headers=headers)
    soup = BeautifulSoup(data.text, 'html.parser')

    ogtitle = soup.select_one('meta[property="og:title"]')['content']
    ogimage = soup.select_one('meta[property="og:image"]')['content']
    ogdesc = soup.select_one('meta[property="og:description"]')['content']
    
    doc = {
       'title' : ogtitle,
       'desc' : ogdesc,
       'image' : ogimage,
       'url' : url_receive,
       'comment' : comment_receive,
       'star' : star_receive,
    }
    
    db.movies.insert_one(doc)

    return redirect('/')

@app.route("/movie", methods=["GET"])
def movie_get():
    all_movies = list(db.movies.find({},{'_id':True, 'title':True, 'desc':True, 'image':True, 'star':True, 'comment':True}))
    
    # ObjectId 값을 String 형식으로 변환
    for movie in all_movies:
        movie['_id'] = str(movie['_id'])
        
    return jsonify({'result':all_movies})
 
@app.route("/view/<id>", methods=["GET"])
def one_find_movie(id):
    
    find_movie = db.movies.find_one({"_id": ObjectId(id)})
    find_movie['_id'] = str(find_movie['_id'])
    
    find_id = db.movies.find_one({'_id' : ObjectId(id)},{'id':True})

    
    return render_template('view.html', movie=find_movie, find_id=find_id)

@app.route("/update/<id>", methods=["GET"])
def update_get(id):
    
    find_movie = db.movies.find_one({"_id": ObjectId(id)})
    find_movie['_id'] = str(find_movie['_id'])
    
    find_id = db.movies.find_one({'_id' : ObjectId(id)},{'id':True})
    
    return render_template('update.html', movie=find_movie, find_id=find_id)

@app.route("/update/<id>", methods=["POST"])
def update_post(id):
    
    comment_receive = request.form['comment_give']
    star_receive = request.form['star_give']

    
    find_movie = db.movies.find_one({"_id": ObjectId(id)})
    find_movie['_id'] = str(find_movie['_id'])
    
    db.movies.update_one({'_id': ObjectId(id)},{'$set':{'comment':comment_receive}})
    db.movies.update_one({'_id': ObjectId(id)},{'$set':{'star':star_receive}})

    return redirect('/view/' + str(id))


# 삭제
@app.route("/delete/<id>", methods=["POST"])
def delete_post(id):
    find_movie = db.movies.find_one({"_id": ObjectId(id)})
    find_movie['_id'] = str(find_movie['_id'])
    
    db.movies.delete_one({'_id': ObjectId(id)})

    return redirect('/')


if __name__ == '__main__':
    app.run('0.0.0.0', port=5001, debug=True)

삭제는 GET이 아닌 POST 방식으로 처리한다.

1. SUBSTRING_INDEX

SUBSTRING_INDEX(
     1번째 인수 : 컬럼명
     2번째 인수 : 기준문자, 구분 문자
     3번째 인수 : 보여질 위치, 위치 기준 음수(-)는 뒷부분 부터, 양수(+)는 앞부분 부터
)

@를 기준으로 텍스트를 쪼개고, 그 중 첫 번째 조각을 가져온다.

select user_id, email, SUBSTRING_INDEX(email, '@', 1) from users
 

@를 기준으로 텍스트를 쪼개고, 맨 끝 조각을 가져온다.

select user_id, email, SUBSTRING_INDEX(email, '@', -1) from users

 

 

2. SUBSTRING 

SUBSTRING(문자열, 출력을 하고싶은 첫 글자의 위치, 몇개의 글자를 출력하고 싶은지)

 

created_at의 시간을 자르고 날짜만 가져오고 싶을 때

select order_no, created_at, substring(created_at,1,10) as date from orders

 

3. CASE

CASE
	WHEN 조건
	THEN '반환 값'
	WHEN 조건
	THEN '반환 값'
	ELSE 'WHEN 조건에 해당 안되는 경우 반환 값'
END
select pu.point_user_id, pu.point,
case 
when pu.point > 10000 then '잘 하고 있어요!'
else '조금 더 달려주세요!'
END as '구분'
from point_users pu;

'SQL' 카테고리의 다른 글

MySQL 접속  (0) 2023.06.14
SQL 4주차 - Subquery  (0) 2023.05.04
SQL 2주차 - GROUP BY, ORDER BY  (0) 2023.05.04
SQL 3주차 - JOIN, UNION  (0) 2023.05.02
SQL 1주차 - BETWEEN, IN, LIKE, LIMIT  (0) 2023.04.27
  • 서브쿼리(subquery)란 다른 쿼리 내부에 포함되어 있는 SELETE 문을 의미하며 서브쿼리는 반드시 괄호(())로 감싸져 있어야한다.

 

1. Where 에 들어가는 Subquery

where 필드명 in (subquery)

select * from users u
where u.user_id in (select o.user_id from orders o 
					where o.payment_method = 'kakaopay');

 

 

2. Select 에 들어가는 Subquery

select 필드명, 필드명, (subquery) from...

select c.checkin_id, c.user_id, c.likes, 
	(select avg(likes) from checkins c2
	where c2.user_id = c.user_id) as avg_like_user
from checkins c;

 

 

3. From 에 들어가는 Subquery 

주로 내가 만든 Select와 이미 있는 테이블을 Join하고 싶을 때 사용한다.

 

course_id별 유저의 체크인 개수 구하기

select c.title,
       a.cnt_checkins,
       b.cnt_total,
       (a.cnt_checkins/b.cnt_total) as ratio
from
(
	select course_id, count(distinct(user_id)) as cnt_checkins from checkins
	group by course_id
) a
inner join
(
	select course_id, count(*) as cnt_total from orders
	group by course_id 
) b on a.course_id = b.course_id
inner join courses c on a.course_id = c.course_id

 

4. with절

with절은 동일한 SQL이 반복되어서 사용될 때 성능을 높이기 위해 사용된다.

table을 만들지 않고도 table 만든 것과 같은 효과를 내는데, 실제로는 temp라는 임시 테이블에 저장되는 것이다.

with
      cte1 as (select a, b from table 1),
      cte2 as (select c, d from table 2), ...

select a from cte1
with table1 as (
	select course_id, count(distinct(user_id)) as cnt_checkins from checkins
	group by course_id
), table2 as (
	select course_id, count(*) as cnt_total from orders
	group by course_id
)
select c.title,
       a.cnt_checkins,
       b.cnt_total,
       (a.cnt_checkins/b.cnt_total) as ratio
from table1 a inner join table2 b on a.course_id = b.course_id
inner join courses c on a.course_id = c.course_id

'SQL' 카테고리의 다른 글

MySQL 접속  (0) 2023.06.14
실전에서 유용한 SQL 문법 (문자열, Case)  (0) 2023.05.04
SQL 2주차 - GROUP BY, ORDER BY  (0) 2023.05.04
SQL 3주차 - JOIN, UNION  (0) 2023.05.02
SQL 1주차 - BETWEEN, IN, LIKE, LIMIT  (0) 2023.04.27

1. group by

~별 ~를 구할 때 group by로 범주를 묶어준다.

 

성씨별 회원수 구하기

select name, count(*) from users
group by name;

 

2.  order by

디폴트는 오름차순 정렬이고

select name, count(*) from users
group by name
order by count(*);

desc를 붙이면 내림차순으로 정렬된다.

select name, count(*) from users
group by name
order by count(*) desc;

'SQL' 카테고리의 다른 글

MySQL 접속  (0) 2023.06.14
실전에서 유용한 SQL 문법 (문자열, Case)  (0) 2023.05.04
SQL 4주차 - Subquery  (0) 2023.05.04
SQL 3주차 - JOIN, UNION  (0) 2023.05.02
SQL 1주차 - BETWEEN, IN, LIKE, LIMIT  (0) 2023.04.27

+ Recent posts